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

#include "Mix/Private/UserFile.h"
#include "Mix/Private/Memory/Buffer.h"
#include "Mix/Private/Graphics/DX11/VertexLayout.h"
#include "Mix/Private/Graphics/DX11/HullShader.h"
#include "Mix/Private/Graphics/DX11/DomainShader.h"
#include "Mix/Private/Graphics/DX11/GeometryShader.h"
#include "Mix/Private/Graphics/DX11/VertexShader.h"
#include "Mix/Private/Graphics/DX11/PixelShader.h"
#include "Mix/Private/Graphics/DX11/ShaderConstant.h"
#include "Mix/Private/Graphics/DX11/VertexBuffer.h"
#include "Mix/Private/Graphics/DX11/IndexBuffer.h"
#include "Mix/Private/Graphics/DX11/TexturePlane.h"
#include "Mix/Private/Graphics/DX11/TextureVolume.h"
#include "Mix/Private/Graphics/DX11/TextureCube.h"
#include "Mix/Private/Graphics/DX11/TextureTarget.h"
#include "Mix/Private/Graphics/DX11/TextureTargetL.h"
#include "Mix/Private/Graphics/DX11/TextureDynamic.h"
#include "Mix/Private/Graphics/DX11/TextureDepth.h"
#include "Mix/Private/Graphics/DX11/Query.h"

namespace Mix{ namespace Graphics{ namespace DX11{

//D3Dリザルトテキスト
const wchar_t* Device::D3DResultTextArray[12] =
{
	L"ファイルが見つかりませんでした",
	L"ステートオブジェクトの一意のインスタンスが多すぎます",
	L"ビューオブジェクトの一意のインスタンスが多すぎます",
	L"リソースごとの ID3D11Device::CreateDeferredContext の呼び出しまたは ID3D11DeviceContext::FinishCommandList の呼び出しの後で最初に呼び出した ID3D11DeviceContext::Map が D3D11_MAP_WRITE_DISCARD ではありませんでした",
	L"メソッドの呼び出しが無効です(メソッドのパラメーターが有効なポインターでない可能性があります)",
	L"このサーフェスとの間で情報を転送している以前のビット演算が不完全です",
	L"デバッグ レイヤーを有効にしてデバイスを作成しようとしましたが、該当するレイヤーがインストールされていません",
	L"無効なパラメーターが渡されました",
	L"システムメモリが不足しています",
	L"正常に処理されたものの、非標準の完了を示す代替成功値です。(失敗)",
	L"エラーは発生していません",
	L"不明なエラーが発生しました",
};

//D3Dバーテックスレイアウトフォーマットテーブル
const DXGI_FORMAT Device::D3DVLFormatTable[Mix::Graphics::VERTEX_ELEMENT_FORMAT_MAX] =
{
	DXGI_FORMAT_R32_FLOAT,
	DXGI_FORMAT_R32G32_FLOAT,
	DXGI_FORMAT_R32G32B32_FLOAT,
	DXGI_FORMAT_R32G32B32A32_FLOAT,
	DXGI_FORMAT_R8G8B8A8_UINT,
	DXGI_FORMAT_R16G16_SINT,
	DXGI_FORMAT_R16G16B16A16_SINT,
	DXGI_FORMAT_R8G8B8A8_UNORM,
	DXGI_FORMAT_R16G16_SNORM,
	DXGI_FORMAT_R16G16B16A16_SNORM,
	DXGI_FORMAT_R16G16_UNORM,
	DXGI_FORMAT_R16G16B16A16_UNORM,
	DXGI_FORMAT_R16G16_FLOAT,
	DXGI_FORMAT_R16G16B16A16_FLOAT,
};

 //D3Dバーテックスレイアウトセマンティックテーブル
const char* Device::D3DVLSemanticTable[Mix::Graphics::VERTEX_ELEMENT_SEMANTIC_MAX] =
{
	"POSITION",
	"BLENDWEIGHT",
	"BLENDINDICES",
	"NORMAL",
	"PSIZE",
	"TEXCOORD",
	"TANGENT",
	"BINORMAL",
	"COLOR",
};

//D3Dプリミティブトポロジテーブル
const D3D11_PRIMITIVE_TOPOLOGY Device::D3DPrimitiveTopologyTable[Mix::Graphics::PT_MAX] =
{
	D3D11_PRIMITIVE_TOPOLOGY_POINTLIST,
	D3D11_PRIMITIVE_TOPOLOGY_LINELIST,
	D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP,
	D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST,
	D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP,
};

//D3Dクエリデスクリプションテーブル
const D3D11_QUERY_DESC Device::D3DQueryDescTable[Mix::Graphics::QT_MAX] =
{
	{ D3D11_QUERY_EVENT, 0 },
	{ D3D11_QUERY_OCCLUSION, 0 },
};

//D3Dクエリ名テーブル
const wchar_t* Device::D3DQueryTextTable[Mix::Graphics::QT_MAX] =
{
	L"EVENT",
	L"OCCLUSION",
};

//D3Dインデックスフォーマットテキストテーブル
const wchar_t* Device::D3DIndexFormatTextTable[Mix::Graphics::IT_MAX] =
{
	L"DXGI_FORMAT_R16_UINT",
	L"DXGI_FORMAT_R32_UINT",
};

//D3Dインデックスフォーマットテーブル
const DXGI_FORMAT Device::D3DIndexFormatTable[Mix::Graphics::IT_MAX] =
{
	DXGI_FORMAT_R16_UINT,
	DXGI_FORMAT_R32_UINT,
};

//インデックスストライドテーブル
const UInt32 Device::D3DIndexStrideTable[Mix::Graphics::IT_MAX] =
{
	2,
	4,
};

//プレゼント( VS4 )
static const UInt8 VS_PRESENT_4[] = {
	#include "Mix/Private/Graphics/DX11/Shader/4/present.vs.inc"
};

//プレゼント( PS4 )
static const UInt8 PS_PRESENT_4[] = {
	#include "Mix/Private/Graphics/DX11/Shader/4/present.ps.inc"
};

//プレゼント( VS5 )
static const UInt8 VS_PRESENT_5[] = {
	#include "Mix/Private/Graphics/DX11/Shader/5/present.vs.inc"
};

//プレゼント( PS5 )
static const UInt8 PS_PRESENT_5[] = {
	#include "Mix/Private/Graphics/DX11/Shader/5/present.ps.inc"
};

////////////////////////////////////////////////////////////////////////////////////////////////////
// Mix::Graphics::DX11::Device
////////////////////////////////////////////////////////////////////////////////////////////////////

Device* Device::CreateInstance( Boolean bWaitVSync )
{
	return MIX_LIB_NEW_T( Mix::Memory::SECTION_GRAPHICS, Device, bWaitVSync );
}

Device::Device( Boolean bWaitVSync ) : Common::Device( bWaitVSync ),
m_pDXGIFactory( NULL ),
m_pDXGIAdapter( NULL ),
m_pDXGIOutput( NULL ),
m_pDXGISwapChain( NULL ),
m_pBackBuffer( NULL ),
m_pBackBufferView( NULL ),
m_pD3DDevice( NULL ),
m_pD3DDeviceContext( NULL ),
m_pPresentVL( NULL ),
m_pPresentVS( NULL ),
m_pPresentPS( NULL ),
m_pPresentVB( NULL ),
m_pPresentTex( NULL ),
m_pPresentRTV( NULL ),
m_pPresentSRV( NULL ),
m_DispMode( Mix::Graphics::IDevice::WINDOW ),
m_DrawPrimitiveCount( 0 )
{
	UInt32 i;
	UInt32 j;
	UInt32 k;

	for( i = 0; i < Mix::Graphics::FILL_MAX; i++ )
	{
		for( j = 0; j < Mix::Graphics::CULL_MAX; j++ )
		{
			for( k = 0; k < 2; k++ )
			{
				m_pRasterizerStateArray[i][j][k] = NULL;
			}
		}
	}

	for( i = 0; i < 2; i++ )
	{
		for( j = 0; j < 2; j++ )
		{
			for( k = 0; k < Mix::Graphics::ZFUNC_MAX; k++ )
			{
				m_pDepthStateArray[i][j][k] = NULL;
			}
		}
	}

	for( i = 0; i < Mix::Graphics::BLEND_MAX; i++ )
	{
		for( j = 0; j < Mix::Graphics::COLOR_WRITE_MASK_MAX; j++ )
		{
			m_pBlendStateArray[i][j] = NULL;
		}
	}

	for( i = 0; i < Mix::Graphics::TEXTUREFILTER_MAX; i++ )
	{
		for( j = 0; j < Mix::Graphics::TEXTUREADDRESS_MAX; j++ )
		{
			m_pSamplerArray[i][j] = NULL;
		}
	}

	m_Viewport.TopLeftX = 0.0f;
	m_Viewport.TopLeftY = 0.0f;
	m_Viewport.Width = 0.0f;
	m_Viewport.Height = 0.0f;
	m_Viewport.MinDepth = 0.0f;
	m_Viewport.MaxDepth = 1.0f;

	m_RasterizeDesc.fillMode = Mix::Graphics::FILL_SOLID;
	m_RasterizeDesc.cullMode = Mix::Graphics::CULL_BACK;
	m_RasterizeDesc.bScissoring = False;

	m_DepthDesc.bTest = True;
	m_DepthDesc.bWrite = True;
	m_DepthDesc.func = Mix::Graphics::ZFUNC_LESSEQUAL;

	m_BlendDesc.type = Mix::Graphics::BLEND_COPY;
	m_BlendDesc.colorWriteMask = Mix::Graphics::COLOR_WRITE_RGBA;

	m_TargetState.rect = Mix::Rectangle( 0, 0, 0, 0 );
	m_TargetState.pT0 = NULL;
	m_TargetState.pT1 = NULL;
	m_TargetState.pT2 = NULL;
	m_TargetState.pT3 = NULL;
	m_TargetState.pDS = NULL;

	ResetDrawState();
}

Device::~Device( void )
{
}

HRESULT Device::CreateBuffer( D3D11_BIND_FLAG bindFlags, UInt32 size, Boolean bDynamic, const void* pInitialData, ID3D11Buffer** ppBuffer )
{
	HRESULT ret;
	D3D11_BUFFER_DESC desc;
	::ID3D11Buffer* pD3DBuffer;

	desc.ByteWidth = size;
	desc.Usage = ( bDynamic == True )? D3D11_USAGE_DYNAMIC : D3D11_USAGE_DEFAULT;
	desc.BindFlags = bindFlags;
	desc.CPUAccessFlags = ( bDynamic == True )? D3D11_CPU_ACCESS_WRITE : 0;
	desc.MiscFlags = 0;
	desc.StructureByteStride = 0;

	if( pInitialData != NULL )
	{
		D3D11_SUBRESOURCE_DATA data;

		data.pSysMem = pInitialData;
		data.SysMemPitch = 0;
		data.SysMemSlicePitch = 0;

		ret = m_pD3DDevice->CreateBuffer( &desc, &data, &pD3DBuffer );
	}
	else
	{
		ret = m_pD3DDevice->CreateBuffer( &desc, NULL, &pD3DBuffer );
	}

	if( ret == S_OK )
	{
		( *ppBuffer ) = pD3DBuffer;
	}

	return ret;
}

HRESULT Device::CreateVertexBuffer( UInt32 count, UInt32 stride, Boolean bDynamic, const void* pInitialData, ID3D11Buffer** ppBuffer )
{
	HRESULT ret;
	D3D11_BUFFER_DESC desc;
	::ID3D11Buffer* pD3DBuffer;

	desc.ByteWidth = ( stride * count );
	desc.Usage = ( bDynamic == True )? D3D11_USAGE_DYNAMIC : D3D11_USAGE_DEFAULT;
	desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
	desc.CPUAccessFlags = ( bDynamic == True )? D3D11_CPU_ACCESS_WRITE : 0;
	desc.MiscFlags = 0;
	desc.StructureByteStride = 0;

	if( pInitialData != NULL )
	{
		D3D11_SUBRESOURCE_DATA data;

		data.pSysMem = pInitialData;
		data.SysMemPitch = 0;
		data.SysMemSlicePitch = 0;

		ret = m_pD3DDevice->CreateBuffer( &desc, &data, &pD3DBuffer );
	}
	else
	{
		ret = m_pD3DDevice->CreateBuffer( &desc, NULL, &pD3DBuffer );
	}

	if( ret == S_OK )
	{
		( *ppBuffer ) = pD3DBuffer;
	}

	return ret;
}

HRESULT Device::CreateIndexBuffer( Mix::Graphics::INDEX_FORMAT format, UInt32 count, Boolean bDynamic, const void* pInitialData, ID3D11Buffer** ppBuffer )
{
	HRESULT ret;
	D3D11_BUFFER_DESC desc;
	::ID3D11Buffer* pD3DBuffer;

	desc.ByteWidth = ( Device::D3DIndexStrideTable[format] * count );
	desc.Usage = ( bDynamic == True )? D3D11_USAGE_DYNAMIC : D3D11_USAGE_DEFAULT;
	desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
	desc.CPUAccessFlags = ( bDynamic == True )? D3D11_CPU_ACCESS_WRITE : 0;
	desc.MiscFlags = 0;
	desc.StructureByteStride = 0;

	if( pInitialData != NULL )
	{
		D3D11_SUBRESOURCE_DATA data;

		data.pSysMem = pInitialData;
		data.SysMemPitch = 0;
		data.SysMemSlicePitch = 0;

		ret = m_pD3DDevice->CreateBuffer( &desc, &data, &pD3DBuffer );
	}
	else
	{
		ret = m_pD3DDevice->CreateBuffer( &desc, NULL, &pD3DBuffer );
	}

	if( ret == S_OK )
	{
		( *ppBuffer ) = pD3DBuffer;
	}

	return ret;
}

HRESULT Device::Map( ID3D11Resource* pResource, Boolean bDynamic, D3D11_MAPPED_SUBRESOURCE& mapped )
{
	return m_pD3DDeviceContext->Map( pResource, 0, ( bDynamic == True )? D3D11_MAP_WRITE_DISCARD : D3D11_MAP_WRITE, 0, &mapped );
}

HRESULT Device::CopyAndMap( ID3D11Resource* pSrcResource, ID3D11Resource* pDstResource, D3D11_MAPPED_SUBRESOURCE& mapped )
{
	m_pD3DDeviceContext->CopyResource( pDstResource, pSrcResource );

	return m_pD3DDeviceContext->Map( pDstResource, 0, D3D11_MAP_READ, 0, &mapped );
}

void Device::Unmap( ID3D11Resource* pResource )
{
	m_pD3DDeviceContext->Unmap( pResource, 0 );
}

void Device::BeginQuery( ID3D11Query* pQuery )
{
	m_pD3DDeviceContext->Begin( pQuery );
}

void Device::EndQuery( ID3D11Query* pQuery )
{
	m_pD3DDeviceContext->End( pQuery );
}

HRESULT Device::GetQueryData( ID3D11Query* pQuery, Boolean bFlush, UInt32& data )
{
	return m_pD3DDeviceContext->GetData( pQuery, &data, sizeof( UInt32 ), ( bFlush == True )? 0 : D3D11_ASYNC_GETDATA_DONOTFLUSH );
}

Mix::Graphics::FORMAT Device::ConvertTextureFormat( DXGI_FORMAT d3dFormat )
{
	switch( d3dFormat )
	{
	case DXGI_FORMAT_D16_UNORM:
		return Mix::Graphics::FMT_D16;
	case DXGI_FORMAT_D32_FLOAT:
		return Mix::Graphics::FMT_D32;
	case DXGI_FORMAT_D24_UNORM_S8_UINT:
		return Mix::Graphics::FMT_D24S8;

	case DXGI_FORMAT_R8G8B8A8_UNORM:
		return Mix::Graphics::FMT_R8G8B8A8;
	case DXGI_FORMAT_A8_UNORM:
		return Mix::Graphics::FMT_A8;
	case DXGI_FORMAT_R16_FLOAT:
		return Mix::Graphics::FMT_R16F;
	case DXGI_FORMAT_R32_FLOAT:
		return Mix::Graphics::FMT_R32F;
	case DXGI_FORMAT_R16G16_FLOAT:
		return Mix::Graphics::FMT_R16G16F;
	case DXGI_FORMAT_R32G32_FLOAT:
		return Mix::Graphics::FMT_R32G32F;
	case DXGI_FORMAT_R16G16B16A16_FLOAT:
		return Mix::Graphics::FMT_R16G16B16A16F;
	case DXGI_FORMAT_R32G32B32A32_FLOAT:
		return Mix::Graphics::FMT_R32G32B32A32F;

	case DXGI_FORMAT_BC1_UNORM:
		return Mix::Graphics::FMT_BC1;
	case DXGI_FORMAT_BC2_UNORM:
		return Mix::Graphics::FMT_BC2;
	case DXGI_FORMAT_BC3_UNORM:
		return Mix::Graphics::FMT_BC3;
	}

	return Mix::Graphics::FMT_UNKNOWN;
}

const wchar_t* Device::GetD3DResultText( HRESULT ret )
{
	switch( ret )
	{
	case D3D11_ERROR_FILE_NOT_FOUND:
		return D3DResultTextArray[0];
	case D3D11_ERROR_TOO_MANY_UNIQUE_STATE_OBJECTS:
		return D3DResultTextArray[1];
	case D3D11_ERROR_TOO_MANY_UNIQUE_VIEW_OBJECTS:
		return D3DResultTextArray[2];
	case D3D11_ERROR_DEFERRED_CONTEXT_MAP_WITHOUT_INITIAL_DISCARD:
		return D3DResultTextArray[3];
	case D3DERR_INVALIDCALL:
		return D3DResultTextArray[4];
	case D3DERR_WASSTILLDRAWING:
		return D3DResultTextArray[5];
	case E_FAIL:
		return D3DResultTextArray[6];
	case E_INVALIDARG:
		return D3DResultTextArray[7];
	case E_OUTOFMEMORY:
		return D3DResultTextArray[8];
	case S_FALSE:
		return D3DResultTextArray[9];
	case S_OK:
		return D3DResultTextArray[10];
	}

	return D3DResultTextArray[11];
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Mix::Graphics::Common::Device
////////////////////////////////////////////////////////////////////////////////////////////////////

Mix::Graphics::ITexture* Device::CreatePlaneTexture(	const wchar_t* pFilePath,
														const Device::TEXTURE_DESC& desc,
														UInt32 subResourceCount,
														const Device::TEXTURE_SUBRESOURCE_DATA* subResources )
{
	if( IsPlaneTextureSupported( desc.format ) == False )
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s] %s[%d]", FAILED_CREATE_TEXTURE_PLANE,
			Mix::STR_FORMAT_NOT_SUPPORT,
			Mix::STR_FILEPATH, pFilePath, Mix::STR_FORMAT, GetFormatText( desc.format ) );

		return NULL;
	}

	HRESULT ret;
	D3D11_TEXTURE2D_DESC d3dDesc;
	D3D11_SHADER_RESOURCE_VIEW_DESC d3dSRVDesc;
	ID3D11Texture2D* pD3DTexture;
	ID3D11ShaderResourceView* pD3DSRView;
	Mix::Graphics::DX11::TexturePlane* pTex;

	d3dDesc.Width = desc.width;
	d3dDesc.Height = desc.height;
	d3dDesc.MipLevels = desc.mipLevels;
	d3dDesc.ArraySize = 1;
	d3dDesc.Format = m_ResourceFmtList[desc.format].format;
	d3dDesc.SampleDesc.Count = 1;
	d3dDesc.SampleDesc.Quality = 0;
	d3dDesc.Usage = D3D11_USAGE_DEFAULT;
	d3dDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
	d3dDesc.CPUAccessFlags = 0;
	d3dDesc.MiscFlags = 0;

	ret = m_pD3DDevice->CreateTexture2D( &d3dDesc, CreateSubResources( subResourceCount, subResources ), &pD3DTexture );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : ID3D11Device::CreateTexture2D %s : %s[%s] %s[%s]", FAILED_CREATE_TEXTURE_PLANE,
			Mix::STR_RETERROR, Mix::STR_FILEPATH, pFilePath, Mix::STR_RESULT, GetD3DResultText( ret ) );

		return NULL;
	}

	d3dSRVDesc.Format = m_ResourceFmtList[desc.format].format;
	d3dSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
	d3dSRVDesc.Texture2D.MostDetailedMip = 0;
	d3dSRVDesc.Texture2D.MipLevels = d3dDesc.MipLevels;

	ret = m_pD3DDevice->CreateShaderResourceView( pD3DTexture, &d3dSRVDesc, &pD3DSRView );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : ID3D11Device::CreateShaderResourceView %s : %s[%s] %s[%s]", FAILED_CREATE_TEXTURE_PLANE,
			Mix::STR_RETERROR, Mix::STR_FILEPATH, pFilePath, Mix::STR_RESULT, GetD3DResultText( ret ) );

		MIX_RELEASE( pD3DTexture );

		return NULL;
	}

	pTex = Mix::Graphics::DX11::TexturePlane::CreateInstance(	this,
																pFilePath,
																desc.width, desc.height, desc.format,
																pD3DTexture, pD3DSRView );
	if( pTex == NULL )
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s]", FAILED_CREATE_TEXTURE_PLANE, Mix::STR_OUTOFMEMORY, Mix::STR_FILEPATH, pFilePath );

		MIX_RELEASE( pD3DSRView );
		MIX_RELEASE( pD3DTexture );

		return NULL;
	}

	return pTex;
}

Mix::Graphics::ITexture* Device::CreateVolumeTexture(	const wchar_t* pFilePath,
														const Device::TEXTURE_DESC& desc,
														UInt32 subResourceCount,
														const Device::TEXTURE_SUBRESOURCE_DATA* subResources )
{
	if( IsVolumeTextureSupported( desc.format ) == False )
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s] %s[%d]", FAILED_CREATE_TEXTURE_VOLUME,
			Mix::STR_FORMAT_NOT_SUPPORT,
			Mix::STR_FILEPATH, pFilePath, Mix::STR_FORMAT, GetFormatText( desc.format ) );

		return NULL;
	}

	HRESULT ret;
	D3D11_TEXTURE3D_DESC d3dDesc;
	D3D11_SHADER_RESOURCE_VIEW_DESC d3dSRVDesc;
	ID3D11Texture3D* pD3DTexture;
	ID3D11ShaderResourceView* pD3DSRView;
	Mix::Graphics::DX11::TextureVolume* pTex;

	d3dDesc.Width = desc.width;
	d3dDesc.Height = desc.height;
	d3dDesc.Depth = desc.depth;
	d3dDesc.MipLevels = desc.mipLevels;
	d3dDesc.Format = m_ResourceFmtList[desc.format].format;
	d3dDesc.Usage = D3D11_USAGE_DEFAULT;
	d3dDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
	d3dDesc.CPUAccessFlags = 0;
	d3dDesc.MiscFlags = 0;

	ret = m_pD3DDevice->CreateTexture3D( &d3dDesc, CreateSubResources( subResourceCount, subResources ), &pD3DTexture );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : ID3D11Device::CreateTexture3D %s : %s[%s] %s[%s]", FAILED_CREATE_TEXTURE_VOLUME,
			Mix::STR_RETERROR, Mix::STR_FILEPATH, pFilePath, Mix::STR_RESULT, GetD3DResultText( ret ) );

		return NULL;
	}

	d3dSRVDesc.Format = m_ResourceFmtList[desc.format].format;
	d3dSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
	d3dSRVDesc.Texture3D.MostDetailedMip = 0;
	d3dSRVDesc.Texture3D.MipLevels = d3dDesc.MipLevels;

	ret = m_pD3DDevice->CreateShaderResourceView( pD3DTexture, &d3dSRVDesc, &pD3DSRView );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : ID3D11Device::CreateShaderResourceView %s : %s[%s] %s[%s]", FAILED_CREATE_TEXTURE_VOLUME,
			Mix::STR_RETERROR, Mix::STR_FILEPATH, pFilePath, Mix::STR_RESULT, GetD3DResultText( ret ) );

		MIX_RELEASE( pD3DTexture );

		return NULL;
	}

	pTex = Mix::Graphics::DX11::TextureVolume::CreateInstance(	this,
																pFilePath,
																desc.width, desc.height, desc.format,
																pD3DTexture, pD3DSRView );
	if( pTex == NULL )
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s]", FAILED_CREATE_TEXTURE_VOLUME, Mix::STR_OUTOFMEMORY, Mix::STR_FILEPATH, pFilePath );

		MIX_RELEASE( pD3DSRView );
		MIX_RELEASE( pD3DTexture );

		return NULL;
	}

	return pTex;
}

Mix::Graphics::ITexture* Device::CreateCubeTexture(		const wchar_t* pFilePath,
														const Device::TEXTURE_DESC& desc,
														UInt32 subResourceCount,
														const Device::TEXTURE_SUBRESOURCE_DATA* subResources )
{
	if( IsCubeTextureSupported( desc.format ) == False )
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s] %s[%d]", FAILED_CREATE_TEXTURE_CUBE,
			Mix::STR_FORMAT_NOT_SUPPORT,
			Mix::STR_FILEPATH, pFilePath, Mix::STR_FORMAT, GetFormatText( desc.format ) );

		return NULL;
	}

	HRESULT ret;
	D3D11_TEXTURE2D_DESC d3dDesc;
	D3D11_SHADER_RESOURCE_VIEW_DESC d3dSRVDesc;
	ID3D11Texture2D* pD3DTexture;
	ID3D11ShaderResourceView* pD3DSRView;
	Mix::Graphics::DX11::TextureCube* pTex;

	d3dDesc.Width = desc.width;
	d3dDesc.Height = desc.height;
	d3dDesc.MipLevels = desc.mipLevels;
	d3dDesc.ArraySize = Mix::Graphics::CUBEMAP_FACE_MAX;
	d3dDesc.Format = m_ResourceFmtList[desc.format].format;
	d3dDesc.SampleDesc.Count = 1;
	d3dDesc.SampleDesc.Quality = 0;
	d3dDesc.Usage = D3D11_USAGE_DEFAULT;
	d3dDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
	d3dDesc.CPUAccessFlags = 0;
	d3dDesc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;

	ret = m_pD3DDevice->CreateTexture2D( &d3dDesc, CreateSubResources( subResourceCount, subResources ), &pD3DTexture );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : ID3D11Device::CreateTexture2D %s : %s[%s] %s[%s]", FAILED_CREATE_TEXTURE_CUBE,
			Mix::STR_RETERROR, Mix::STR_FILEPATH, pFilePath, Mix::STR_RESULT, GetD3DResultText( ret ) );

		return NULL;
	}

	d3dSRVDesc.Format = m_ResourceFmtList[desc.format].format;
	d3dSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
	d3dSRVDesc.TextureCube.MostDetailedMip	= 0;
	d3dSRVDesc.TextureCube.MipLevels = d3dDesc.MipLevels;

	ret = m_pD3DDevice->CreateShaderResourceView( pD3DTexture, &d3dSRVDesc, &pD3DSRView );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : ID3D11Device::CreateShaderResourceView %s : %s[%s] %s[%s]", FAILED_CREATE_TEXTURE_CUBE,
			Mix::STR_RETERROR, Mix::STR_FILEPATH, pFilePath, Mix::STR_RESULT, GetD3DResultText( ret ) );

		MIX_RELEASE( pD3DTexture );

		return NULL;
	}

	pTex = Mix::Graphics::DX11::TextureCube::CreateInstance(	this,
																NULL,
																desc.width, desc.height, desc.format,
																pD3DTexture, pD3DSRView, NULL );
	if( pTex == NULL )
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s]", FAILED_CREATE_TEXTURE_CUBE, Mix::STR_OUTOFMEMORY, Mix::STR_FILEPATH, pFilePath );

		MIX_RELEASE( pD3DSRView );
		MIX_RELEASE( pD3DTexture );

		return NULL;
	}

	return pTex;
}

const D3D11_SUBRESOURCE_DATA* Device::CreateSubResources( UInt32 count, const Device::TEXTURE_SUBRESOURCE_DATA* pSubRes )
{
	MIX_ASSERT( pSubRes != NULL );
	MIX_ASSERT( count > 0 );

	m_SubResTemp.clear();
	m_SubResTemp.resize( count );

	const Device::TEXTURE_SUBRESOURCE_DATA* pSrc = pSubRes;
	const Device::TEXTURE_SUBRESOURCE_DATA* pSrcEnd = pSrc + count;
	D3D11_SUBRESOURCE_DATA* pDst = &( m_SubResTemp[0] );

	while( pSrc != pSrcEnd )
	{
		pDst->pSysMem = pSrc->pMem;
		pDst->SysMemPitch = pSrc->memRowPitch;
		pDst->SysMemSlicePitch = pSrc->memSlicePitch;

		pSrc++;
		pDst++;
	}

	return &( m_SubResTemp[0] );
}

void Device::OnDispose( void )
{
	BOOL bFullscreen;
	UInt32 i;
	UInt32 j;
	UInt32 k;

	MIX_RELEASE( m_pPresentSRV );
	MIX_RELEASE( m_pPresentRTV );
	MIX_RELEASE( m_pPresentTex );
	MIX_RELEASE( m_pPresentVB );
	MIX_RELEASE( m_pPresentPS );
	MIX_RELEASE( m_pPresentVS );
	MIX_RELEASE( m_pPresentVL );

	if( ( m_pDXGISwapChain != NULL ) &&
		( m_pDXGISwapChain->GetFullscreenState( &bFullscreen, NULL ) == S_OK ) &&
		( bFullscreen == TRUE ) )
	{
		m_pDXGISwapChain->SetFullscreenState( FALSE, NULL );
	}

	for( i = 0; i < Mix::Graphics::TEXTUREFILTER_MAX; i++ )
	{
		for( j = 0; j < Mix::Graphics::TEXTUREADDRESS_MAX; j++ )
		{
			MIX_RELEASE( m_pSamplerArray[i][j] );
		}
	}

	for( i = 0; i < Mix::Graphics::BLEND_MAX; i++ )
	{
		for( j = 0; j < Mix::Graphics::COLOR_WRITE_MASK_MAX; j++ )
		{
			MIX_RELEASE( m_pBlendStateArray[i][j] );
		}
	}

	for( i = 0; i < 2; i++ )
	{
		for( j = 0; j < 2; j++ )
		{
			for( k = 0; k < Mix::Graphics::ZFUNC_MAX; k++ )
			{
				MIX_RELEASE( m_pDepthStateArray[i][j][k] );
			}
		}
	}

	for( i = 0; i < Mix::Graphics::FILL_MAX; i++ )
	{
		for( j = 0; j < Mix::Graphics::CULL_MAX; j++ )
		{
			for( k = 0; k < 2; k++ )
			{
				MIX_RELEASE( m_pRasterizerStateArray[i][j][k] );
			}
		}
	}

	ResetTargetState();
	ResetDrawState();

	MIX_RELEASE( m_pBackBufferView );
	MIX_RELEASE( m_pBackBuffer );
	MIX_RELEASE( m_pD3DDeviceContext );
	MIX_RELEASE( m_pD3DDevice );

	MIX_RELEASE( m_pDXGISwapChain );
	MIX_RELEASE( m_pDXGIOutput );
	MIX_RELEASE( m_pDXGIAdapter );
	MIX_RELEASE( m_pDXGIFactory );
}

Mix::Graphics::ITexture* Device::OnCreateTexture(	const wchar_t* pFilePath,
													const Device::TEXTURE_DESC& desc,
													UInt32 subResourceCount,
													const Device::TEXTURE_SUBRESOURCE_DATA* subResources )
{
	if( desc.type == Mix::Plugin::Graphics::ITextureKit::PLANE )
	{
		return CreatePlaneTexture( pFilePath, desc, subResourceCount, subResources );
	}
	else if( desc.type == Mix::Plugin::Graphics::ITextureKit::VOLUME )
	{
		return CreateVolumeTexture( pFilePath, desc, subResourceCount, subResources );
	}
	else if( desc.type == Mix::Plugin::Graphics::ITextureKit::CUBE )
	{
		return CreateCubeTexture( pFilePath, desc, subResourceCount, subResources );
	}
	else
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s] %s[%d]", FAILED_CREATE_TEXTURE,
			Mix::STR_TYPE_NOT_SUPPORT,
			Mix::STR_FILEPATH, pFilePath, Mix::STR_TYPE, desc.type );
	}

	return NULL;
}

Boolean Device::Initialize( const Mix::Point& targetSize, Mix::Graphics::SHADER_MODEL shaderModel, Boolean bFullscreen, Mix::UserFile* pSysReport )
{
	MIX_ASSERT( shaderModel != Mix::Graphics::SHADER_MODEL_3 );

	const D3D_FEATURE_LEVEL featureLevelTable[] =
	{
		D3D_FEATURE_LEVEL_11_0,
		D3D_FEATURE_LEVEL_10_1,
		D3D_FEATURE_LEVEL_10_0,
	};

	const UInt32 featureLevelMax = sizeof( featureLevelTable ) / sizeof( D3D_FEATURE_LEVEL );

	const D3D11_FILL_MODE fillTable[Mix::Graphics::FILL_MAX] =
	{
		D3D11_FILL_WIREFRAME,
		D3D11_FILL_SOLID,
	};

	const D3D11_CULL_MODE cullTable[Mix::Graphics::CULL_MAX] =
	{
		D3D11_CULL_NONE,
		D3D11_CULL_FRONT,
		D3D11_CULL_BACK,
	};

	const D3D11_FILTER texFilterTable[Mix::Graphics::TEXTUREFILTER_MAX] =
	{
		D3D11_FILTER_MIN_MAG_MIP_POINT,
		D3D11_FILTER_MIN_MAG_MIP_LINEAR,
		D3D11_FILTER_ANISOTROPIC,
	};

	const UInt32 texAnisotropyTable[Mix::Graphics::TEXTUREFILTER_MAX] =
	{
		0,
		0,
		8,
	};

	const D3D11_TEXTURE_ADDRESS_MODE texAddressTable[Mix::Graphics::TEXTUREADDRESS_MAX] =
	{
		D3D11_TEXTURE_ADDRESS_WRAP,
		D3D11_TEXTURE_ADDRESS_CLAMP,
	};

	const D3D11_COMPARISON_FUNC zFuncTable[Mix::Graphics::ZFUNC_MAX] =
	{
		D3D11_COMPARISON_ALWAYS,
		D3D11_COMPARISON_NEVER,
		D3D11_COMPARISON_LESS,
		D3D11_COMPARISON_EQUAL,
		D3D11_COMPARISON_LESS_EQUAL,
		D3D11_COMPARISON_GREATER,
		D3D11_COMPARISON_NOT_EQUAL,
		D3D11_COMPARISON_GREATER_EQUAL,
	};

	const UInt8 colorWriteMaskTable[Mix::Graphics::COLOR_WRITE_MASK_MAX] =
	{
		D3D11_COLOR_WRITE_ENABLE_ALL,
		D3D11_COLOR_WRITE_ENABLE_RED | D3D11_COLOR_WRITE_ENABLE_GREEN | D3D11_COLOR_WRITE_ENABLE_BLUE,
		D3D11_COLOR_WRITE_ENABLE_ALPHA,
	};

	HRESULT ret;
	UInt32 i;
	UInt32 j;
	UInt32 k;
	UInt32 createFlags;
	UInt32 featureLevelStart;
	UInt32 featureLevelNum;
	UInt32 numMode;
	UInt32 supportFlags;
	DXGI_MODE_DESC dispMode;
	DXGI_MODE_DESC bestDispMode;
	DXGI_SWAP_CHAIN_DESC scDesc;
	Mix::String d3dx11ModuleName;
	D3D11CreateDeviceFunc D3D11CreateDevice;
	CreateDXGIFactoryFunc CreateDXGIFactory;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// D3D11 モジュール
	////////////////////////////////////////////////////////////////////////////////////////////////////

	// ロード

	if( m_D3D11Module.Load( L"d3d11.dll" ) == False )
	{
		::MessageBoxW( m_pEngine->GetWindowHandle(), L"DirectX が正しくインストールされていません D3D11(1)", L"エラー", MB_OK | MB_ICONSTOP );
		return False;
	}

	// ファンクションの登録

	if( m_D3D11Module.RegisterFunction( L"D3D11CreateDevice" ) == False )
	{
		::MessageBoxW( m_pEngine->GetWindowHandle(), L"DirectX が正しくインストールされていません D3D11(2)", L"エラー", MB_OK | MB_ICONSTOP );
		return False;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// DXGI モジュール
	////////////////////////////////////////////////////////////////////////////////////////////////////

	// ロード

	if( m_DXGIModule.Load( L"dxgi.dll" ) == False )
	{
		::MessageBoxW( m_pEngine->GetWindowHandle(), L"DirectX が正しくインストールされていません DXGI(1)", L"エラー", MB_OK | MB_ICONSTOP );
		return False;
	}

	// ファンクションの登録

	if( m_DXGIModule.RegisterFunction( L"CreateDXGIFactory" ) == False )
	{
		::MessageBoxW( m_pEngine->GetWindowHandle(), L"DirectX が正しくインストールされていません DXGI(2)", L"エラー", MB_OK | MB_ICONSTOP );
		return False;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 初期化
	////////////////////////////////////////////////////////////////////////////////////////////////////

	D3D11CreateDevice = static_cast<D3D11CreateDeviceFunc>( m_D3D11Module.GetFunction( L"D3D11CreateDevice" ) );
	CreateDXGIFactory = static_cast<CreateDXGIFactoryFunc>( m_DXGIModule.GetFunction( L"CreateDXGIFactory" ) );

	// ファクトリを作成

	ret = CreateDXGIFactory( __uuidof( IDXGIFactory ), reinterpret_cast<void**>( &m_pDXGIFactory ) );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : CreateDXGIFactory %s : Result[%s]", FAILED_INITIALIZE, Mix::STR_RETERROR, GetD3DResultText( ret ) );
		return False;
	}

	// システムレポートの記録開始

	if( pSysReport->Open() == True )
	{
		pSysReport->WriteLine( L"////////////////////////////////////////////////////////////////////////////////////////////////////" );
		pSysReport->WriteLine( L"// グラフィックス( DirectX11 )                                                                    //" );
		pSysReport->WriteLine( L"////////////////////////////////////////////////////////////////////////////////////////////////////" );
		pSysReport->WriteLine( L"" );

		pSysReport->Close();
	}

	// アダプタを決定

	ret = m_pDXGIFactory->EnumAdapters( 0, &m_pDXGIAdapter );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : IDXGIFactory::EnumAdapters %s : Result[%s]", FAILED_INITIALIZE, Mix::STR_RETERROR, GetD3DResultText( ret ) );
		return False;
	}

	// アダプタ情報をレポート

	if( pSysReport->Open() == True )
	{
		DXGI_ADAPTER_DESC adapterDesc;

		pSysReport->WriteLine( L"[ディスプレイアダプタ]" );

		if( m_pDXGIAdapter->GetDesc( &adapterDesc ) == S_OK )
		{
			pSysReport->WriteLine( L"  説明 \"%s\"", adapterDesc.Description );
			pSysReport->WriteLine( L"  ベンダーID 0x%08x", adapterDesc.VendorId );
			pSysReport->WriteLine( L"  デバイスID 0x%08x", adapterDesc.DeviceId );
			pSysReport->WriteLine( L"  サブシステムID 0x%08x", adapterDesc.SubSysId );
			pSysReport->WriteLine( L"  リビジョン 0x%08x", adapterDesc.Revision );
			pSysReport->WriteLine( L"  ビデオメモリ %fMB", static_cast<Float32>( adapterDesc.DedicatedVideoMemory ) / 1048576.0f );
			pSysReport->WriteLine( L"  システムメモリ %fMB", static_cast<Float32>( adapterDesc.DedicatedSystemMemory ) / 1048576.0f );
			pSysReport->WriteLine( L"  共有システムメモリ %fMB", static_cast<Float32>( adapterDesc.SharedSystemMemory ) / 1048576.0f );
		}
		else
		{
			pSysReport->WriteLine( L"取得できませんでした" );
		}

		pSysReport->WriteLine( L"" );

		pSysReport->Close();
	}

	// デバイスとデバイスコンテキストを作成

#ifdef _DEBUG
	createFlags = ( D3D11_CREATE_DEVICE_DEBUG/* | D3D11_CREATE_DEVICE_SWITCH_TO_REF*/ );
#else //_DEBUG
	createFlags = 0;
#endif //_DEBUG

	switch( shaderModel )
	{
	case Mix::Graphics::SHADER_MODEL_4:
		featureLevelStart = 1;
		break;
	case Mix::Graphics::SHADER_MODEL_5:
		featureLevelStart = 0;
		break;
	}

	featureLevelNum = featureLevelMax - featureLevelStart;
	MIX_ASSERT( featureLevelNum > 0 );

	ret = D3D11CreateDevice(	m_pDXGIAdapter,
								D3D_DRIVER_TYPE_UNKNOWN,
								NULL,
								createFlags,
								&( featureLevelTable[featureLevelStart] ),
								featureLevelNum,
								D3D11_SDK_VERSION,
								&m_pD3DDevice,
								&m_FeatureLevel,
								&m_pD3DDeviceContext );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : D3D11CreateDevice %s : Result[%s]", FAILED_INITIALIZE, Mix::STR_RETERROR, GetD3DResultText( ret ) );
		return False;
	}

	// シェーダーモデルを決定

	if( shaderModel == Mix::Graphics::SHADER_MODEL_4 )
	{
		MIX_ASSERT( m_FeatureLevel != D3D_FEATURE_LEVEL_11_0 );

		switch( m_FeatureLevel )
		{
		case D3D_FEATURE_LEVEL_10_0:
		case D3D_FEATURE_LEVEL_10_1:
			m_ShaderModel = Mix::Graphics::SHADER_MODEL_4;
			break;

		default:
			MessageBoxW( m_pEngine->GetWindowHandle(), L"お使いの環境では、シェーダーモデル 4 は使用できません", L"エラー", MB_OK | MB_ICONSTOP );
			MIX_LOG_ERROR( L"%s : お使いの環境では、シェーダーモデル４は使用できません", FAILED_INITIALIZE );
			return False;
		}
	}
	else if( shaderModel == Mix::Graphics::SHADER_MODEL_5 )
	{
		switch( m_FeatureLevel )
		{
		case D3D_FEATURE_LEVEL_10_0:
		case D3D_FEATURE_LEVEL_10_1:
			m_ShaderModel = Mix::Graphics::SHADER_MODEL_4;
			MIX_LOG_WARNING( L"%s : お使いの環境では、シェーダーモデル５は使用できないため、シェーダーモデル 4 を使用します。", FAILED_INITIALIZE );
			break;

		case D3D_FEATURE_LEVEL_11_0:
			m_ShaderModel = Mix::Graphics::SHADER_MODEL_5;
			break;

		default:
			MessageBoxW( m_pEngine->GetWindowHandle(), L"お使いの環境では、シェーダーモデル 5 は使用できません", L"エラー", MB_OK | MB_ICONSTOP );
			MIX_LOG_ERROR( L"%s : お使いの環境では、シェーダーモデル 5 は使用できません", FAILED_INITIALIZE );
			return False;
		}
	}

	if( m_FeatureLevel == D3D_FEATURE_LEVEL_10_0 )
	{
		D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS hopt;

		m_Caps.flags =	GEOMETRY_SHADER |
						OUTPUTSTREAM |
						TEXTURE_ARRAY |
						TEXTURE_BC4_BC5 |
						ALPHA_TO_COVERAGE |
						OCCLUSIONQUERY |
						SEPARATEALPHABLEND |
						MIRRORONE |
						OVERLAP_VERTEXELEMENT |
						INDEPENDENTWRITEMASKS |
						INSTANCING;

		if( ( m_pD3DDevice->CheckFeatureSupport( D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS, &hopt, sizeof( hopt ) ) == S_OK ) &&
			( hopt.ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x == TRUE ) )
        {
			m_Caps.flags |= COMPUTE_SHADER;
			::wcscpy_s( m_Caps.shaderModel, L"4_x" );
		}
		else
		{
			::wcscpy_s( m_Caps.shaderModel, L"4_0" );
		}

		m_Caps.maxTextureSize = 8192;
		m_Caps.maxCubeTextureSize = 8192;
		m_Caps.maxVolumeTextureRange = 2048;
		m_Caps.maxTextureRepeat = 8192;
		m_Caps.maxAnisotropy = 16;
		m_Caps.maxPrimitive = ( 2 ^ 32 );
		m_Caps.maxTarget = 8;
	}
	else if( m_FeatureLevel == D3D_FEATURE_LEVEL_10_1 )
	{
		D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS hopt;

		m_Caps.flags =	GEOMETRY_SHADER |
						OUTPUTSTREAM |
						TEXTURE_ARRAY |
						CUBETEXTURE_ARRAY |
						TEXTURE_BC4_BC5 |
						ALPHA_TO_COVERAGE |
						OCCLUSIONQUERY |
						SEPARATEALPHABLEND |
						MIRRORONE |
						OVERLAP_VERTEXELEMENT |
						INDEPENDENTWRITEMASKS |
						INSTANCING;

		if( ( m_pD3DDevice->CheckFeatureSupport( D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS, &hopt, sizeof( hopt ) ) == S_OK ) &&
			( hopt.ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x == TRUE ) )
        {
			m_Caps.flags |= COMPUTE_SHADER;
			::wcscpy_s( m_Caps.shaderModel, L"4_x" );
		}
		else
		{
			::wcscpy_s( m_Caps.shaderModel, L"4_0" );
		}

		m_Caps.maxTextureSize = 8192;
		m_Caps.maxCubeTextureSize = 8192;
		m_Caps.maxVolumeTextureRange = 2048;
		m_Caps.maxTextureRepeat = 8192;
		m_Caps.maxAnisotropy = 16;
		m_Caps.maxPrimitive = 0xFFFFFFFF;
		m_Caps.maxTarget = 8;
	}
	else if( m_FeatureLevel == D3D_FEATURE_LEVEL_11_0 )
	{
		m_Caps.flags =	GEOMETRY_SHADER |
						COMPUTE_SHADER |
						HAL_DOMAIN_SHADER |
						OUTPUTSTREAM |
						TEXTURE_ARRAY |
						CUBETEXTURE_ARRAY |
						TEXTURE_BC4_BC5 |
						TEXTURE_BC6H_BC7 |
						ALPHA_TO_COVERAGE |
						EXTEND_FORMAT |
						HIGHCOLOR_FORMAT_10XR |
						OCCLUSIONQUERY |
						SEPARATEALPHABLEND |
						MIRRORONE |
						OVERLAP_VERTEXELEMENT |
						INDEPENDENTWRITEMASKS |
						INSTANCING;

		::wcscpy_s( m_Caps.shaderModel, L"5_0" );

		m_Caps.maxTextureSize = 16384;
		m_Caps.maxCubeTextureSize = 16384;
		m_Caps.maxVolumeTextureRange = 2048;
		m_Caps.maxTextureRepeat = 16384;
		m_Caps.maxAnisotropy = 16;
		m_Caps.maxPrimitive = 0xFFFFFFFF;
		m_Caps.maxTarget = 8;
	}

	// デバイスの固有能力をレポート

	if( pSysReport->Open() == True )
	{
		pSysReport->WriteLine( L"  [デバイスの固有能力]" );
		pSysReport->WriteLine( L"    [%s] ジオメトリシェーダー" , ( ( m_Caps.flags & GEOMETRY_SHADER ) == GEOMETRY_SHADER )? L"○" : L"×" );
		pSysReport->WriteLine( L"    [%s] コンピュートシェーダー" , ( ( m_Caps.flags & COMPUTE_SHADER ) == COMPUTE_SHADER )? L"○" : L"×" );
		pSysReport->WriteLine( L"    [%s] ハル、ドメインシェーダー" , ( ( m_Caps.flags & HAL_DOMAIN_SHADER ) == HAL_DOMAIN_SHADER )? L"○" : L"×" );
		pSysReport->WriteLine( L"    [%s] ストリーム出力" , ( ( m_Caps.flags & OUTPUTSTREAM ) == OUTPUTSTREAM )? L"○" : L"×" );
		pSysReport->WriteLine( L"    [%s] テクスチャー配列" , ( ( m_Caps.flags & TEXTURE_ARRAY ) == TEXTURE_ARRAY )? L"○" : L"×" );
		pSysReport->WriteLine( L"    [%s] キューブテクスチャ配列" , ( ( m_Caps.flags & CUBETEXTURE_ARRAY ) == CUBETEXTURE_ARRAY )? L"○" : L"×" );
		pSysReport->WriteLine( L"    [%s] BC4/BC5圧縮" , ( ( m_Caps.flags & TEXTURE_BC4_BC5 ) == TEXTURE_BC4_BC5 )? L"○" : L"×" );
		pSysReport->WriteLine( L"    [%s] BC6H/BC7圧縮" , ( ( m_Caps.flags & TEXTURE_BC6H_BC7 ) == TEXTURE_BC6H_BC7 )? L"○" : L"×" );
		pSysReport->WriteLine( L"    [%s] アルファトゥカバレッジ(マルチサンプリング)" , ( ( m_Caps.flags & ALPHA_TO_COVERAGE ) == ALPHA_TO_COVERAGE )? L"○" : L"×" );
		pSysReport->WriteLine( L"    [%s] 拡張フォーマット(BGRAなど)" , ( ( m_Caps.flags & EXTEND_FORMAT ) == EXTEND_FORMAT )? L"○" : L"×" );
		pSysReport->WriteLine( L"    [%s] 10ビットXRハイカラーフォーマット" , ( ( m_Caps.flags & HIGHCOLOR_FORMAT_10XR ) == HIGHCOLOR_FORMAT_10XR )? L"○" : L"×" );
		pSysReport->WriteLine( L"    [%s] オクルージョンクエリ" , ( ( m_Caps.flags & OCCLUSIONQUERY ) == OCCLUSIONQUERY )? L"○" : L"×" );
		pSysReport->WriteLine( L"    [%s] 個別のアルファブレンディング" , ( ( m_Caps.flags & SEPARATEALPHABLEND ) == SEPARATEALPHABLEND )? L"○" : L"×" );
		pSysReport->WriteLine( L"    [%s] ミラーワンス(テクスチャアドレッシングモード)" , ( ( m_Caps.flags & MIRRORONE ) == MIRRORONE )? L"○" : L"×" );
		pSysReport->WriteLine( L"    [%s] 頂点要素のオーバーラップ" , ( ( m_Caps.flags & OVERLAP_VERTEXELEMENT ) == OVERLAP_VERTEXELEMENT )? L"○" : L"×" );
		pSysReport->WriteLine( L"    [%s] 独立した書き込みマスク(レンダリングターゲット)" , ( ( m_Caps.flags & INDEPENDENTWRITEMASKS ) == INDEPENDENTWRITEMASKS )? L"○" : L"×" );
		pSysReport->WriteLine( L"    [%s] 頂点バッファの内容を繰り返し描画" , ( ( m_Caps.flags & INSTANCING ) == INSTANCING )? L"○" : L"×" );
		pSysReport->WriteLine( L"    [%s] シェーダーモデル", m_Caps.shaderModel );
		pSysReport->WriteLine( L"    [%d] 最大テクスチャサイズ", m_Caps.maxTextureSize );
		pSysReport->WriteLine( L"    [%d] 最大キューブテクスチャサイズ", m_Caps.maxCubeTextureSize );
		pSysReport->WriteLine( L"    [%d] 最大ボリュームテクスチャ範囲", m_Caps.maxVolumeTextureRange );
		pSysReport->WriteLine( L"    [%d] 最大異方性", m_Caps.maxAnisotropy );
		pSysReport->WriteLine( L"    [%d] 最大プリミティブ数", m_Caps.maxPrimitive );
		pSysReport->WriteLine( L"    [%d] 同時レンダリングターゲット数", m_Caps.maxTarget );
		pSysReport->WriteLine( L"" );

		pSysReport->Close();
	}

	//バーテックスレイアウトのフォーマットをレポート
	if( pSysReport->Open() == True )
	{
		const wchar_t* vlFormatNameTable[Mix::Graphics::VERTEX_ELEMENT_FORMAT_MAX] =
		{
			L"R32_FLOAT",
			L"R32G32_FLOAT",
			L"R32G32B32_FLOAT",
			L"R32G32B32A32_FLOAT",
			L"R8G8B8A8_UINT",
			L"R16G16_SINT",
			L"R16G16B16A16_SINT",
			L"R8G8B8A8_UNORM",
			L"R16G16_SNORM",
			L"R16G16B16A16_SNORM",
			L"R16G16_UNORM",
			L"R16G16B16A16_UNORM",
			L"R16G16_FLOAT",
			L"R16G16B16A16_FLOAT",
		};

		pSysReport->WriteLine( L"[バーテックスレイアウト]" );

		for( i = 0; i < Mix::Graphics::VERTEX_ELEMENT_FORMAT_MAX; i++ )
		{
			supportFlags = 0;
			m_pD3DDevice->CheckFormatSupport( Device::D3DVLFormatTable[i], &supportFlags );

			pSysReport->WriteLine( L"  [%s] %s",
				( ( supportFlags & D3D11_FORMAT_SUPPORT_IA_VERTEX_BUFFER ) == D3D11_FORMAT_SUPPORT_IA_VERTEX_BUFFER )? L"○" : L"×",
				vlFormatNameTable[i] );
		}

		pSysReport->WriteLine( L"" );

		pSysReport->Close();
	}

	// インデックスタイプのサポートリストを作成

	for( i = 0; i < Mix::Graphics::IT_MAX; i++ )
	{
		supportFlags = 0;
		m_pD3DDevice->CheckFormatSupport( D3DIndexFormatTable[i], &supportFlags );
		m_IndexTypeSupportList[i] = ( ( supportFlags & D3D11_FORMAT_SUPPORT_IA_INDEX_BUFFER ) == D3D11_FORMAT_SUPPORT_IA_INDEX_BUFFER );
	}

	// リソースの対応フォーマットを決定

	m_ResourceFmtList[FMT_UNKNOWN].format = DXGI_FORMAT_UNKNOWN;
	m_ResourceFmtList[FMT_D16].format = DXGI_FORMAT_D16_UNORM;
	m_ResourceFmtList[FMT_D32].format = DXGI_FORMAT_D32_FLOAT;
	m_ResourceFmtList[FMT_D24S8].format = DXGI_FORMAT_D24_UNORM_S8_UINT;
	m_ResourceFmtList[FMT_R8G8B8A8].format = DXGI_FORMAT_B8G8R8A8_UNORM;//DXGI_FORMAT_R8G8B8A8_UNORM;
	m_ResourceFmtList[FMT_A8].format = DXGI_FORMAT_A8_UNORM;
	m_ResourceFmtList[FMT_R16F].format = DXGI_FORMAT_R16_FLOAT;
	m_ResourceFmtList[FMT_R32F].format = DXGI_FORMAT_R32_FLOAT;
	m_ResourceFmtList[FMT_R16G16F].format = DXGI_FORMAT_R16G16_FLOAT;
	m_ResourceFmtList[FMT_R32G32F].format = DXGI_FORMAT_R32G32_FLOAT;
	m_ResourceFmtList[FMT_R16G16B16A16F].format = DXGI_FORMAT_R16G16B16A16_FLOAT;
	m_ResourceFmtList[FMT_R32G32B32A32F].format = DXGI_FORMAT_R32G32B32A32_FLOAT;
	m_ResourceFmtList[FMT_BC1].format = DXGI_FORMAT_BC1_UNORM;
	m_ResourceFmtList[FMT_BC2].format = DXGI_FORMAT_BC2_UNORM;
	m_ResourceFmtList[FMT_BC3].format = DXGI_FORMAT_BC3_UNORM;

	for( i = 0; i < Mix::Graphics::FMT_MAX; i++ )
	{
		supportFlags = 0;
		m_pD3DDevice->CheckFormatSupport( m_ResourceFmtList[i].format, &supportFlags );

		m_ResourceFmtList[i].flags = 0;

		if( ( supportFlags & D3D11_FORMAT_SUPPORT_TEXTURE2D ) == D3D11_FORMAT_SUPPORT_TEXTURE2D )
		{
			m_ResourceFmtList[i].flags |= Device::RS_PLANE;
		}

		if( ( supportFlags & D3D11_FORMAT_SUPPORT_TEXTURE3D ) == D3D11_FORMAT_SUPPORT_TEXTURE3D )
		{
			m_ResourceFmtList[i].flags |= Device::RS_VOLUME;
		}

		if( ( supportFlags & D3D11_FORMAT_SUPPORT_TEXTURECUBE ) == D3D11_FORMAT_SUPPORT_TEXTURECUBE )
		{
			m_ResourceFmtList[i].flags |= Device::RS_CUBE;
		}

		if( ( supportFlags & D3D11_FORMAT_SUPPORT_DEPTH_STENCIL ) == D3D11_FORMAT_SUPPORT_DEPTH_STENCIL )
		{
			m_ResourceFmtList[i].flags |= Device::RS_DEPTH_STENCIL;
		}

		if( ( supportFlags & D3D11_FORMAT_SUPPORT_RENDER_TARGET ) == D3D11_FORMAT_SUPPORT_RENDER_TARGET )
		{
			m_ResourceFmtList[i].flags |= Device::RS_TARGET;
		}

		if( ( supportFlags & D3D11_FORMAT_SUPPORT_CPU_LOCKABLE ) == D3D11_FORMAT_SUPPORT_CPU_LOCKABLE )
		{
			m_ResourceFmtList[i].flags |= Device::RS_DYNAMIC;
		}
	}

	// 各種フォーマットをレポート

	if( pSysReport->Open() == True )
	{
		Mix::Graphics::FORMAT texFormatTable[] =
		{
			Mix::Graphics::FMT_D16,
			Mix::Graphics::FMT_D32,
			Mix::Graphics::FMT_D24S8,
			Mix::Graphics::FMT_R8G8B8A8,
			Mix::Graphics::FMT_A8,
			Mix::Graphics::FMT_R16F,
			Mix::Graphics::FMT_R32F,
			Mix::Graphics::FMT_R16G16F,
			Mix::Graphics::FMT_R32G32F,
			Mix::Graphics::FMT_R16G16B16A16F,
			Mix::Graphics::FMT_R32G32B32A32F,
			Mix::Graphics::FMT_BC1,
			Mix::Graphics::FMT_BC2,
			Mix::Graphics::FMT_BC3,
			Mix::Graphics::FMT_UNKNOWN,
		};

		UInt32 testFlags;

		////////////////////////////////////////////////////////////////////////////////////////////////////

		pSysReport->WriteLine( L"[ファイルテクスチャ]" );

		//プレーン
		pSysReport->WriteLine( L"  [プレーン]" );
		for( i = 0; texFormatTable[i] != Mix::Graphics::FMT_UNKNOWN; i++ )
		{
			testFlags = Device::RS_PLANE;

			pSysReport->WriteLine( L"    [%s] %s",
				( ( m_ResourceFmtList[texFormatTable[i]].flags & testFlags ) == testFlags )? L"○" : L"×",
				GetFormatText( texFormatTable[i] ) );
		}

		//ボリューム
		pSysReport->WriteLine( L"  [ボリューム]" );
		for( i = 0; texFormatTable[i] != Mix::Graphics::FMT_UNKNOWN; i++ )
		{
			testFlags = Device::RS_VOLUME;

			pSysReport->WriteLine( L"    [%s] %s",
				( ( m_ResourceFmtList[texFormatTable[i]].flags & testFlags ) == testFlags )? L"○" : L"×",
				GetFormatText( texFormatTable[i] ) );
		}

		//キューブ
		pSysReport->WriteLine( L"  [キューブ]" );
		for( i = 0; texFormatTable[i] != Mix::Graphics::FMT_UNKNOWN; i++ )
		{
			testFlags = Device::RS_CUBE;

			pSysReport->WriteLine( L"    [%s] %s",
				( ( m_ResourceFmtList[texFormatTable[i]].flags & testFlags ) == testFlags )? L"○" : L"×",
				GetFormatText( texFormatTable[i] ) );
		}

		pSysReport->WriteLine( L"" );

		////////////////////////////////////////////////////////////////////////////////////////////////////

		pSysReport->WriteLine( L"[ダイナミックテクスチャ]" );

		//プレーン
		pSysReport->WriteLine( L"  [プレーン]" );
		for( i = 0; texFormatTable[i] != Mix::Graphics::FMT_UNKNOWN; i++ )
		{
			testFlags = Device::RS_PLANE | Device::RS_DYNAMIC;

			pSysReport->WriteLine( L"    [%s] %s",
				( ( m_ResourceFmtList[texFormatTable[i]].flags & testFlags ) == testFlags )? L"○" : L"×",
				GetFormatText( texFormatTable[i] ) );
		}

		pSysReport->WriteLine( L"" );

		////////////////////////////////////////////////////////////////////////////////////////////////////

		pSysReport->WriteLine( L"[ターゲットテクスチャ]" );

		//プレーン
		pSysReport->WriteLine( L"  [プレーン]" );
		for( i = 0; texFormatTable[i] != Mix::Graphics::FMT_UNKNOWN; i++ )
		{
			testFlags = Device::RS_PLANE | Device::RS_TARGET;

			pSysReport->WriteLine( L"    [%s] %s",
				( ( m_ResourceFmtList[texFormatTable[i]].flags & testFlags ) == testFlags )? L"○" : L"×",
				GetFormatText( texFormatTable[i] ) );
		}

		//キューブ
		pSysReport->WriteLine( L"  [キューブ]" );
		for( i = 0; texFormatTable[i] != Mix::Graphics::FMT_UNKNOWN; i++ )
		{
			testFlags = Device::RS_CUBE | Device::RS_TARGET;

			pSysReport->WriteLine( L"    [%s] %s",
				( ( m_ResourceFmtList[texFormatTable[i]].flags & testFlags ) == testFlags )? L"○" : L"×",
				GetFormatText( texFormatTable[i] ) );
		}

		pSysReport->WriteLine( L"" );

		////////////////////////////////////////////////////////////////////////////////////////////////////

		pSysReport->WriteLine( L"[デプステクスチャ]" );

		//プレーン
		pSysReport->WriteLine( L"  [プレーン]" );
		for( i = 0; texFormatTable[i] != Mix::Graphics::FMT_UNKNOWN; i++ )
		{
			testFlags = Device::RS_PLANE | Device::RS_DEPTH_STENCIL;

			pSysReport->WriteLine( L"    [%s] %s",
				( ( m_ResourceFmtList[texFormatTable[i]].flags & testFlags ) == testFlags )? L"○" : L"×",
				GetFormatText( texFormatTable[i] ) );
		}

		pSysReport->WriteLine( L"" );

		////////////////////////////////////////////////////////////////////////////////////////////////////

		pSysReport->Close();
	}

	// ディスプレイモードを列挙

	ret = m_pDXGIAdapter->EnumOutputs( 0, &m_pDXGIOutput );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : IDXGIAdapter::EnumOutputs %s : Result[%s]", FAILED_INITIALIZE,
			Mix::STR_RETERROR, GetD3DResultText( ret ) );

		return False;
	}

	ret = m_pDXGIOutput->GetDisplayModeList( DXGI_FORMAT_R8G8B8A8_UNORM, 0, &numMode, NULL );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : IDXGIOutput::GetDisplayModeList %s(1) : Result[%s]", FAILED_INITIALIZE,
			Mix::STR_RETERROR, GetD3DResultText( ret ) );

		return False;
	}

	m_DisplayModeList.resize( numMode );

	ret = m_pDXGIOutput->GetDisplayModeList( DXGI_FORMAT_R8G8B8A8_UNORM, 0, &numMode, &( m_DisplayModeList[0] ) );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : IDXGIOutput::GetDisplayModeList %s(2) : Result[%s]", FAILED_INITIALIZE,
			Mix::STR_RETERROR, GetD3DResultText( ret ) );

		return False;
	}

	// ディスプレイモードを決定

	Mix::Memory::Zero( &dispMode, sizeof( dispMode ) );
	Mix::Memory::Zero( &bestDispMode, sizeof( bestDispMode ) );
	dispMode.Width = targetSize.x;
	dispMode.Height = targetSize.y;
	dispMode.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	ret = m_pDXGIOutput->FindClosestMatchingMode( &dispMode, &bestDispMode, m_pD3DDevice );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : IDXGIOutput::FindClosestMatchingMode %s : Result[%s]", FAILED_INITIALIZE,
			Mix::STR_RETERROR, GetD3DResultText( ret ) );

		return False;
	}

	// スワップチェーンの作成

	if( m_pEngine->IsSizeableWindow() == True )
	{
		Mix::Point clientSize = m_pEngine->GetClientSize();

		scDesc.BufferDesc.Width	= clientSize.x;
		scDesc.BufferDesc.Height = clientSize.y;
	}
	else
	{
		scDesc.BufferDesc.Width	= bestDispMode.Width;
		scDesc.BufferDesc.Height = bestDispMode.Height;
	}

	scDesc.BufferDesc.Format			= bestDispMode.Format;
	scDesc.BufferDesc.RefreshRate		= bestDispMode.RefreshRate;
	scDesc.BufferDesc.Scaling			= bestDispMode.Scaling;
	scDesc.BufferDesc.ScanlineOrdering	= bestDispMode.ScanlineOrdering;
	scDesc.SampleDesc.Count				= 1;
	scDesc.SampleDesc.Quality			= 0;
	scDesc.BufferUsage					= DXGI_USAGE_RENDER_TARGET_OUTPUT;
	scDesc.BufferCount					= 1;
	scDesc.OutputWindow					= m_pEngine->GetWindowHandle();
	scDesc.Windowed						= TRUE;
	scDesc.SwapEffect					= DXGI_SWAP_EFFECT_DISCARD;
	scDesc.Flags						= DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;

	ret = m_pDXGIFactory->CreateSwapChain( m_pD3DDevice, &scDesc, &m_pDXGISwapChain );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : IDXGIFactory::CreateSwapChain %s : Result[%s]", FAILED_INITIALIZE,
			Mix::STR_RETERROR, GetD3DResultText( ret ) );

		return False;
	}

	ret = m_pDXGIFactory->MakeWindowAssociation( m_pEngine->GetWindowHandle(), DXGI_MWA_NO_WINDOW_CHANGES | DXGI_MWA_NO_ALT_ENTER );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : IDXGIFactory::MakeWindowAssociation %s : Result[%s]", FAILED_INITIALIZE,
			Mix::STR_RETERROR, GetD3DResultText( ret ) );

		return False;
	}

	// 可変サイズウィンドウの IDXGISwapChain::Present 用リソースを作成 //

	if( m_pEngine->IsSizeableWindow() == True )
	{
		const UInt8* vsSrc = ( m_ShaderModel == Mix::Graphics::SHADER_MODEL_4 )? VS_PRESENT_4 : VS_PRESENT_5;
		UIntT vsSrcSize = ( m_ShaderModel == Mix::Graphics::SHADER_MODEL_4 )? sizeof( VS_PRESENT_4 ) : sizeof( VS_PRESENT_5 );

		const UInt8* psSrc = ( m_ShaderModel == Mix::Graphics::SHADER_MODEL_4 )? PS_PRESENT_4 : PS_PRESENT_5;
		UIntT psSrcSize = ( m_ShaderModel == Mix::Graphics::SHADER_MODEL_4 )? sizeof( PS_PRESENT_4 ) : sizeof( PS_PRESENT_5 );

		D3D11_INPUT_ELEMENT_DESC vlElems[2];

		D3D11_BUFFER_DESC vbDesc;

		D3D11_TEXTURE2D_DESC texDesc;
		D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
		D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;

		// バーテックスシェーダー

		ret = m_pD3DDevice->CreateVertexShader( vsSrc, vsSrcSize, NULL, &m_pPresentVS );
		if( ret != S_OK )
		{
			MIX_LOG_ERROR( L"%s : ID3D11Device::CreateVertexShader %s ( Present ) : Result[%s]", FAILED_INITIALIZE,
				Mix::STR_RETERROR, GetD3DResultText( ret ) );

			return False;
		}

		// ピクセルシェーダー

		ret = m_pD3DDevice->CreatePixelShader( psSrc, psSrcSize, NULL, &m_pPresentPS );
		if( ret != S_OK )
		{
			MIX_LOG_ERROR( L"%s : ID3D11Device::CreatePixelShader %s ( Present ) : Result[%s]", FAILED_INITIALIZE,
				Mix::STR_RETERROR, GetD3DResultText( ret ) );

			return False;
		}

		// バーテックスレイアウト

		vlElems[0].SemanticName = "POSITION";
		vlElems[0].SemanticIndex = 0;
		vlElems[0].Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
		vlElems[0].InputSlot = 0;
		vlElems[0].AlignedByteOffset = 0;
		vlElems[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
		vlElems[0].InstanceDataStepRate = 0;

		vlElems[1].SemanticName = "TEXCOORD";
		vlElems[1].SemanticIndex = 0;
		vlElems[1].Format = DXGI_FORMAT_R32G32_FLOAT;
		vlElems[1].InputSlot = 0;
		vlElems[1].AlignedByteOffset = 16;
		vlElems[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
		vlElems[1].InstanceDataStepRate = 0;

		ret = m_pD3DDevice->CreateInputLayout( vlElems, 2, vsSrc, vsSrcSize, &m_pPresentVL );
		if( ret != S_OK )
		{
			MIX_LOG_ERROR( L"%s : ID3D11Device::CreateInputLayout %s ( Present ) : Result[%s]", FAILED_INITIALIZE,
				Mix::STR_RETERROR, GetD3DResultText( ret ) );

			return False;
		}

		// バーテックスバッファー

		vbDesc.ByteWidth = 24 * 4;
		vbDesc.Usage = D3D11_USAGE_DYNAMIC;
		vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
		vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
		vbDesc.MiscFlags = 0;
		vbDesc.StructureByteStride = 0;

		ret = m_pD3DDevice->CreateBuffer( &vbDesc, NULL, &m_pPresentVB );
		if( ret != S_OK )
		{
			MIX_LOG_ERROR( L"%s : ID3D11Device::CreateBuffer %s ( Present ) : Result[%s]", FAILED_INITIALIZE,
				Mix::STR_RETERROR, GetD3DResultText( ret ) );

			return False;
		}

		// テクスチャ

		texDesc.Width = bestDispMode.Width;
		texDesc.Height = bestDispMode.Height;
		texDesc.MipLevels = 1;
		texDesc.ArraySize = 1;
		texDesc.Format = scDesc.BufferDesc.Format;
		texDesc.SampleDesc.Count = 1;
		texDesc.SampleDesc.Quality = 0;
		texDesc.Usage = D3D11_USAGE_DEFAULT;
		texDesc.BindFlags = ( D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET );
		texDesc.CPUAccessFlags = 0;
		texDesc.MiscFlags = 0;

		rtvDesc.Format = scDesc.BufferDesc.Format;
		rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
		rtvDesc.Texture2D.MipSlice = 0;

		srvDesc.Format = scDesc.BufferDesc.Format;
		srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
		srvDesc.Texture2D.MostDetailedMip = 0;
		srvDesc.Texture2D.MipLevels = 1;

		ret = m_pD3DDevice->CreateTexture2D( &texDesc, NULL, &m_pPresentTex );
		if( ret != S_OK )
		{
			MIX_LOG_ERROR( L"%s : ID3D11Device::CreateTexture2D %s ( Present ) : Result[%s]", FAILED_INITIALIZE,
				Mix::STR_RETERROR, GetD3DResultText( ret ) );

			return False;
		}

		ret = m_pD3DDevice->CreateRenderTargetView( m_pPresentTex, &rtvDesc, &m_pPresentRTV );
		if( ret != S_OK )
		{
			MIX_LOG_ERROR( L"%s : ID3D11Device::CreateRenderTargetView %s ( Present ) : Result[%s]", FAILED_INITIALIZE,
				Mix::STR_RETERROR, GetD3DResultText( ret ) );

			return False;
		}

		ret = m_pD3DDevice->CreateShaderResourceView( m_pPresentTex, &srvDesc, &m_pPresentSRV );
		if( ret != S_OK )
		{
			MIX_LOG_ERROR( L"%s : ID3D11Device::CreateShaderResourceView %s ( Present ) : Result[%s]", FAILED_INITIALIZE,
				Mix::STR_RETERROR, GetD3DResultText( ret ) );

			return False;
		}
	}

	// バックバッファを作成

	m_ScreenSize.Set( bestDispMode.Width, bestDispMode.Height ); // CreateBackBuffer で使用するので先に設定しておく
	m_TargetState.rect.Set( 0, 0, m_ScreenSize.x, m_ScreenSize.y );

	ret = CreateBackBuffer( FAILED_INITIALIZE );
	if( ret != S_OK )
	{
		return False;
	}

	SetViewBounds( m_TargetState.rect );
	SetScissorBounds( m_TargetState.rect );

	UpdateScreenValidRect();

	// ラスタライザステートを作成

	for( i = 0; i < Mix::Graphics::FILL_MAX; i++ )
	{
		for( j = 0; j < Mix::Graphics::CULL_MAX; j++ )
		{
			for( k = 0; k < 2; k++ )
			{
				D3D11_RASTERIZER_DESC desc;

				desc.FillMode = fillTable[i];
				desc.CullMode = cullTable[j];
				desc.FrontCounterClockwise = FALSE;
				desc.DepthBias = 0;
				desc.SlopeScaledDepthBias = 0.0f;
				desc.DepthBiasClamp = 0.0f;
				desc.DepthClipEnable = TRUE;
				desc.ScissorEnable = ( k == 1 );
				desc.MultisampleEnable = FALSE;
				desc.AntialiasedLineEnable = FALSE;

				m_pD3DDevice->CreateRasterizerState( &desc, &m_pRasterizerStateArray[i][j][k] );
			}
		}
	}

	// デプスステートを作成

	for( i = 0; i < 2; i++ )
	{
		for( j = 0; j < 2; j++ )
		{
			for( k = 0; k < Mix::Graphics::ZFUNC_MAX; k++ )
			{
				D3D11_DEPTH_STENCIL_DESC desc;

				Mix::Memory::Zero( &desc, sizeof( desc ) );

				desc.DepthEnable = ( i == 1 );
				desc.DepthWriteMask = ( j == 0 )? D3D11_DEPTH_WRITE_MASK_ZERO : D3D11_DEPTH_WRITE_MASK_ALL;
				desc.DepthFunc = zFuncTable[k];

				m_pD3DDevice->CreateDepthStencilState( &desc, &m_pDepthStateArray[i][j][k] );
			}
		}
	}

	// ブレンドステートを作成

	for( i = 0; i < Mix::Graphics::BLEND_MAX; i++ )
	{
		Boolean bBlendEnabled = ( i != Mix::Graphics::BLEND_COPY );

		D3D11_BLEND srcBlend;
		D3D11_BLEND destBlend;
		D3D11_BLEND_OP blendOp;
		D3D11_BLEND srcBlendAlpha;
		D3D11_BLEND destBlendAlpha;
		D3D11_BLEND_OP blendOpAlpha;

		switch( i )
		{
		case Mix::Graphics::BLEND_COPY:
			srcBlend		= D3D11_BLEND_ONE;
			destBlend		= D3D11_BLEND_ZERO;
			blendOp			= D3D11_BLEND_OP_ADD;
			srcBlendAlpha	= D3D11_BLEND_ONE;
			destBlendAlpha	= D3D11_BLEND_ZERO;
			blendOpAlpha	= D3D11_BLEND_OP_ADD;
			break;

		case Mix::Graphics::BLEND_NORMAL:
			srcBlend		= D3D11_BLEND_SRC_ALPHA;
			destBlend		= D3D11_BLEND_INV_SRC_ALPHA;
			blendOp			= D3D11_BLEND_OP_ADD;
			srcBlendAlpha	= D3D11_BLEND_SRC_ALPHA;
			destBlendAlpha	= D3D11_BLEND_INV_SRC_ALPHA;
			blendOpAlpha	= D3D11_BLEND_OP_ADD;
			break;

		case Mix::Graphics::BLEND_ADD:
			srcBlend		= D3D11_BLEND_SRC_ALPHA;
			destBlend		= D3D11_BLEND_ONE;
			blendOp			= D3D11_BLEND_OP_ADD;
			srcBlendAlpha	= D3D11_BLEND_SRC_ALPHA;
			destBlendAlpha	= D3D11_BLEND_ONE;
			blendOpAlpha	= D3D11_BLEND_OP_ADD;
			break;

		case Mix::Graphics::BLEND_SUB:
			srcBlend		= D3D11_BLEND_SRC_ALPHA;
			destBlend		= D3D11_BLEND_ONE;
			blendOp			= D3D11_BLEND_OP_REV_SUBTRACT;
			srcBlendAlpha	= D3D11_BLEND_SRC_ALPHA;
			destBlendAlpha	= D3D11_BLEND_ONE;
			blendOpAlpha	= D3D11_BLEND_OP_REV_SUBTRACT;
			break;

		case Mix::Graphics::BLEND_MUL:
			srcBlend		= D3D11_BLEND_ZERO;
			destBlend		= D3D11_BLEND_SRC_COLOR;
			blendOp			= D3D11_BLEND_OP_ADD;
			srcBlendAlpha	= D3D11_BLEND_ZERO;
			destBlendAlpha	= D3D11_BLEND_SRC_ALPHA;
			blendOpAlpha	= D3D11_BLEND_OP_ADD;
			break;

		case Mix::Graphics::BLEND_SCREEN:
			srcBlend		= D3D11_BLEND_INV_DEST_COLOR;
			destBlend		= D3D11_BLEND_ONE;
			blendOp			= D3D11_BLEND_OP_ADD;
			srcBlendAlpha	= D3D11_BLEND_INV_DEST_ALPHA;
			destBlendAlpha	= D3D11_BLEND_ONE;
			blendOpAlpha	= D3D11_BLEND_OP_ADD;
			break;
		}

		for( j = 0; j < Mix::Graphics::COLOR_WRITE_MASK_MAX; j++ )
		{
			UInt8 colorWriteMask = colorWriteMaskTable[j];

			D3D11_BLEND_DESC desc;

			desc.AlphaToCoverageEnable = FALSE;
			desc.IndependentBlendEnable = FALSE;

			for( k = 0; k < 8; k++ )
			{
				desc.RenderTarget[k].BlendEnable			= bBlendEnabled;
				desc.RenderTarget[k].RenderTargetWriteMask	= colorWriteMask;
				desc.RenderTarget[k].SrcBlend				= srcBlend;
				desc.RenderTarget[k].DestBlend				= destBlend;
				desc.RenderTarget[k].BlendOp				= blendOp;
				desc.RenderTarget[k].SrcBlendAlpha			= srcBlendAlpha;
				desc.RenderTarget[k].DestBlendAlpha			= destBlendAlpha;
				desc.RenderTarget[k].BlendOpAlpha			= blendOpAlpha;
			}

			m_pD3DDevice->CreateBlendState( &desc, &m_pBlendStateArray[i][j] );
		}
	}

	// サンプラーステートを作成 //

	for( i = 0; i < Mix::Graphics::TEXTUREFILTER_MAX; i++ )
	{
		for( j = 0; j < Mix::Graphics::TEXTUREADDRESS_MAX; j++ )
		{
			D3D11_SAMPLER_DESC desc;

			desc.Filter = texFilterTable[i];
			desc.AddressU = texAddressTable[j];
			desc.AddressV = texAddressTable[j];
			desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
			desc.MipLODBias = 0.0f;
			desc.MaxAnisotropy = texAnisotropyTable[i];
			desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
			desc.BorderColor[0] = 0.0f;
			desc.BorderColor[1] = 0.0f;
			desc.BorderColor[2] = 0.0f;
			desc.BorderColor[3] = 0.0f;
			desc.MinLOD = 0;
			desc.MaxLOD = D3D11_FLOAT32_MAX;

			m_pD3DDevice->CreateSamplerState( &desc, &( m_pSamplerArray[i][j] ) );
		}
	}

	if( pSysReport->Open() == True )
	{
		const wchar_t* texFilterNameTable[Mix::Graphics::TEXTUREFILTER_MAX] =
		{
			L"POINT",
			L"LINEAR",
			L"ANISOTROPIC",
		};

		const wchar_t* texAddressNameTable[Mix::Graphics::TEXTUREADDRESS_MAX] =
		{
			L"WRAP",
			L"CLAMP",
		};

		pSysReport->WriteLine( L"[サンプラーステート]" );

		for( i = 0; i < Mix::Graphics::TEXTUREFILTER_MAX; i++ )
		{
			for( j = 0; j < Mix::Graphics::TEXTUREADDRESS_MAX; j++ )
			{
				pSysReport->WriteLine( L"  [%s] %s %s",
					( m_pSamplerArray[i][j] != NULL )? L"○" : L"×",
					texFilterNameTable[i],
					texAddressNameTable[j] );
			}
		}

		pSysReport->WriteLine( L"" );

		pSysReport->Close();
	}

	if( bFullscreen == True )
	{
		//フルスクリーンモードに切り替える
		SetDisplayMode( Mix::Graphics::IDevice::FULLSCREEN );
	}

	// デバイスの初期化完了を通知 //

	UInt32 shaderModelNo = 0;
	UInt32 refreshRate = 0;

	switch( m_ShaderModel )
	{
	case Mix::Graphics::SHADER_MODEL_4:
		shaderModelNo = 4;
		break;
	case Mix::Graphics::SHADER_MODEL_5:
		shaderModelNo = 5;
		break;
	}

	if( bFullscreen == False )
	{
		HDC hDC = ::GetDC( m_pEngine->GetWindowHandle() );
		if( hDC != NULL )
		{
			refreshRate = ::GetDeviceCaps( hDC, VREFRESH );
			::ReleaseDC( m_pEngine->GetWindowHandle(), hDC );
		}
	}
	else
	{
		refreshRate = static_cast<UINT>( scDesc.BufferDesc.RefreshRate.Numerator );
	}

	MIX_LOG_INFO( L"DirectX11( ShaderModel%d ) : Mode[%s] Size[%dx%d] BackBufferFormat[%s] RefreshRate[%dHz]",
		shaderModelNo,
		( bFullscreen == True )? L"Fullscreen" : L"Window",
		scDesc.BufferDesc.Width,
		scDesc.BufferDesc.Height,
		GetFormatText( ConvertTextureFormat( scDesc.BufferDesc.Format ) ),
		refreshRate );

	////////////////////////////////////////////////////////////////////////////////////////////////////

	return True;
}

Boolean Device::MessageProc( UInt32 msg, WPARAM wParam, LPARAM lParam )
{
	switch( msg )
	{
	case WM_SYSKEYDOWN:
		if( wParam == VK_RETURN )
		{
			ToggleDisplayMode();
		}
		break;

	case WM_ACTIVATEAPP:
		if( LOWORD( wParam ) == WA_INACTIVE )
		{
			if( m_DispMode == Mix::Graphics::IDevice::FULLSCREEN )
			{
				m_DispMode = Mix::Graphics::IDevice::WINDOW;
			}
		}
		break;

	case WM_SIZE:
		ResizeBackBuffer();
		break;
	}

	return True;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Mix::Graphics::IDevice
////////////////////////////////////////////////////////////////////////////////////////////////////

Boolean Device::IsHullShaderSupported( void ) const
{
	return ( MIX_TESTBIT( m_Caps.flags, Device::HAL_DOMAIN_SHADER ) == Device::HAL_DOMAIN_SHADER );
}

Boolean Device::IsDomainShaderSupported( void ) const
{
	return ( MIX_TESTBIT( m_Caps.flags, Device::HAL_DOMAIN_SHADER ) == Device::HAL_DOMAIN_SHADER );
}

Boolean Device::IsGeometryShaderSupported( void ) const
{
	return True;
}

Boolean Device::IsShaderConstantSupported( void ) const
{
	return True;
}

Boolean Device::IsIndexSupported( Mix::Graphics::INDEX_FORMAT format ) const
{
	return m_IndexTypeSupportList[format];
}

Boolean Device::IsPlaneTextureSupported( Mix::Graphics::FORMAT format ) const
{
	return ( ( m_ResourceFmtList[format].flags & Device::RS_PLANE ) == Device::RS_PLANE );
}

Boolean Device::IsVolumeTextureSupported( Mix::Graphics::FORMAT format ) const
{
	return ( ( m_ResourceFmtList[format].flags & Device::RS_VOLUME ) == Device::RS_VOLUME );
}

Boolean Device::IsCubeTextureSupported( Mix::Graphics::FORMAT format ) const
{
	return ( ( m_ResourceFmtList[format].flags & Device::RS_CUBE ) == Device::RS_CUBE );
}

Boolean Device::IsDynamicPlaneTextureSupported( Mix::Graphics::FORMAT format ) const
{
	return ( ( m_ResourceFmtList[format].flags & ( Device::RS_PLANE | Device::RS_DYNAMIC ) ) == ( Device::RS_PLANE | Device::RS_DYNAMIC ) );
}

Boolean Device::IsTargetPlaneTextureSupported( Mix::Graphics::FORMAT format ) const
{
	return ( ( m_ResourceFmtList[format].flags & ( Device::RS_PLANE | Device::RS_TARGET ) ) == ( Device::RS_PLANE | Device::RS_TARGET ) );
}

Boolean Device::IsLockableTargetPlaneTextureSupported( Mix::Graphics::FORMAT format ) const
{
	if( IsTargetPlaneTextureSupported( format ) == False )
	{
		return False;
	}

	return ( ( m_ResourceFmtList[format].flags & ( Device::RS_PLANE | Device::RS_DYNAMIC ) ) == ( Device::RS_PLANE | Device::RS_DYNAMIC ) );
}

Boolean Device::IsTargetCubeTextureSupported( Mix::Graphics::FORMAT format ) const
{
	return ( ( m_ResourceFmtList[format].flags & ( Device::RS_CUBE | Device::RS_TARGET ) ) == ( Device::RS_CUBE | Device::RS_TARGET ) );
}

Boolean Device::IsDepthTextureSupported( Mix::Graphics::FORMAT format ) const
{
	return ( ( m_ResourceFmtList[format].flags & Device::RS_DEPTH_STENCIL ) == Device::RS_DEPTH_STENCIL );
}

Boolean Device::CreateHullShaderFromFile( const wchar_t* pFilePath, Mix::Graphics::IHullShader** ppHullShader )
{
	if( MIX_TESTBIT( m_Caps.flags, Device::HAL_DOMAIN_SHADER ) != Device::HAL_DOMAIN_SHADER )
	{
		MIX_LOG_ERROR( L"%s : シェーダーモデル 5 のみ使用できます。", FAILED_CREATE_HULL_SHADER );
		return False;
	}

	if( ( pFilePath == NULL ) ||
		( ::wcslen( pFilePath ) == 0 ) ||
		( ppHullShader == NULL ) )
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s] ppHullShader[%s]",
			FAILED_CREATE_HULL_SHADER,
			Mix::STR_ILLEGALARG,
			Mix::STR_FILEPATH,
			MIX_LOG_STR( pFilePath ),
			MIX_LOG_PTR( ppHullShader ) );

		return False;
	}

	HRESULT ret;
	Mix::Memory::IBuffer* pBuffer;
	ID3D11HullShader* pD3DHullShader;
	Mix::Graphics::DX11::HullShader* pHullShader;

	if( m_pFileMgr->CreateBufferFromFile( pFilePath, &pBuffer ) == False )
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s]", FAILED_CREATE_HULL_SHADER, Mix::STR_FILENOTFOUND, Mix::STR_FILEPATH, pFilePath );
		return False;
	}

	ret = m_pD3DDevice->CreateHullShader( pBuffer->GetConstPointer(), pBuffer->GetSize(), NULL, &pD3DHullShader );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : CreateHullShader %s : %s[%s] %s[%s]", FAILED_CREATE_HULL_SHADER,
			Mix::STR_RETERROR, Mix::STR_FILEPATH, pFilePath, Mix::STR_RESULT, GetD3DResultText( ret ) );
		MIX_RELEASE( pBuffer );
		return False;
	}

	pHullShader = Mix::Graphics::DX11::HullShader::CreateInstance( this, pD3DHullShader );
	if( pHullShader == NULL )
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s]", FAILED_CREATE_HULL_SHADER, Mix::STR_OUTOFMEMORY, Mix::STR_FILEPATH, pFilePath );
		MIX_RELEASE( pD3DHullShader );
		MIX_RELEASE( pBuffer );
		return False;
	}

	( *ppHullShader ) = pHullShader;

	return True;
}

Boolean Device::CreateHullShaderFromMemory( const void* pSrc, UInt32 srcSize, Mix::Graphics::IHullShader** ppHullShader, const wchar_t* pDebugName )
{
	if( MIX_TESTBIT( m_Caps.flags, Device::HAL_DOMAIN_SHADER ) != Device::HAL_DOMAIN_SHADER )
	{
		MIX_LOG_ERROR( L"%s : シェーダーモデル 5 のみ使用できます", FAILED_CREATE_HULL_SHADER );
		return False;
	}

	if( ( pSrc == NULL ) ||
		( srcSize == 0 ) ||
		( ppHullShader == NULL ) )
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s] : pSrc[%s] srcSize[%d] ppHullShader[%s]",
			FAILED_CREATE_HULL_SHADER,
			Mix::STR_ILLEGALARG,
			Mix::STR_DEBUGNAME,
			MIX_SAFE_NAME( pDebugName ),
			MIX_LOG_PTR( pSrc ),
			srcSize,
			MIX_LOG_PTR( ppHullShader ) );

		return False;
	}

	HRESULT ret;
	ID3D11HullShader* pD3DHullShader;
	Mix::Graphics::DX11::HullShader* pHullShader;

	ret = m_pD3DDevice->CreateHullShader( pSrc, srcSize, NULL, &pD3DHullShader );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : CreateHullShader %s : %s[%s] %s[%s]", FAILED_CREATE_HULL_SHADER,
			Mix::STR_RETERROR, Mix::STR_DEBUGNAME, MIX_SAFE_NAME( pDebugName ), Mix::STR_RESULT, GetD3DResultText( ret ) );

		return False;
	}

	pHullShader = Mix::Graphics::DX11::HullShader::CreateInstance( this, pD3DHullShader );
	if( pHullShader == NULL )
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s]", FAILED_CREATE_HULL_SHADER,
			Mix::STR_OUTOFMEMORY, Mix::STR_DEBUGNAME, MIX_SAFE_NAME( pDebugName ) );

		MIX_RELEASE( pD3DHullShader );

		return False;
	}

	( *ppHullShader ) = pHullShader;

	return True;
}

Boolean Device::CreateDomainShaderFromFile( const wchar_t* pFilePath, Mix::Graphics::IDomainShader** ppDomainShader )
{
	if( MIX_TESTBIT( m_Caps.flags, Device::HAL_DOMAIN_SHADER ) != Device::HAL_DOMAIN_SHADER )
	{
		MIX_LOG_ERROR( L"%s : シェーダーモデル 5 のみ使用できます", FAILED_CREATE_DOMAIN_SHADER );
		return False;
	}

	if( ( pFilePath == NULL ) ||
		( ::wcslen( pFilePath ) == 0 ) ||
		( ppDomainShader == NULL ) )
	{
		MIX_LOG_ERROR( L"%s : %s : pFilePath[%s] ppDomainShader[%s]",
			FAILED_CREATE_DOMAIN_SHADER,
			Mix::STR_ILLEGALARG,
			MIX_LOG_STR( pFilePath ),
			MIX_LOG_PTR( ppDomainShader ) );

		return False;
	}

	HRESULT ret;
	Mix::Memory::IBuffer* pBuffer;
	ID3D11DomainShader* pD3DDomainShader;
	Mix::Graphics::DX11::DomainShader* pDomainShader;

	if( m_pFileMgr->CreateBufferFromFile( pFilePath, &pBuffer ) == False )
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s]", FAILED_CREATE_DOMAIN_SHADER,
			Mix::STR_FILENOTFOUND,
			Mix::STR_FILEPATH, pFilePath );

		return False;
	}

	ret = m_pD3DDevice->CreateDomainShader( pBuffer->GetConstPointer(), pBuffer->GetSize(), NULL, &pD3DDomainShader );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : CreateDomainShader %s : %s[%s] %s[%s]", FAILED_CREATE_DOMAIN_SHADER,
			Mix::STR_RETERROR, Mix::STR_FILEPATH, pFilePath, Mix::STR_RESULT, GetD3DResultText( ret ) );

		MIX_RELEASE( pBuffer );

		return False;
	}

	pDomainShader = Mix::Graphics::DX11::DomainShader::CreateInstance( this, pD3DDomainShader );
	if( pDomainShader == NULL )
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s]", FAILED_CREATE_DOMAIN_SHADER,
			Mix::STR_OUTOFMEMORY, Mix::STR_FILEPATH, pFilePath );

		MIX_RELEASE( pD3DDomainShader );
		MIX_RELEASE( pBuffer );

		return False;
	}

	( *ppDomainShader ) = pDomainShader;

	return True;
}

Boolean Device::CreateDomainShaderFromMemory( const void* pSrc, UInt32 srcSize, Mix::Graphics::IDomainShader** ppDomainShader, const wchar_t* pDebugName )
{
	if( MIX_TESTBIT( m_Caps.flags, Device::HAL_DOMAIN_SHADER ) != Device::HAL_DOMAIN_SHADER )
	{
		MIX_LOG_ERROR( L"%s : シェーダーモデル 5 のみ使用できます", FAILED_CREATE_DOMAIN_SHADER );
		return False;
	}

	if( ( pSrc == NULL ) ||
		( srcSize == 0 ) ||
		( ppDomainShader == NULL ) )
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s] : pSrc[%s] srcSize[%d] ppDomainShader[%s]", FAILED_CREATE_DOMAIN_SHADER,
			Mix::STR_ILLEGALARG,
			Mix::STR_DEBUGNAME,
			MIX_SAFE_NAME( pDebugName ),
			MIX_LOG_STR( pSrc ),
			srcSize,
			MIX_LOG_PTR( ppDomainShader ) );

		return False;
	}

	HRESULT ret;
	ID3D11DomainShader* pD3DDomainShader;
	Mix::Graphics::DX11::DomainShader* pDomainShader;

	ret = m_pD3DDevice->CreateDomainShader( pSrc, srcSize, NULL, &pD3DDomainShader );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : CreateDomainShader %s : %s[%s] %s[%s]", FAILED_CREATE_DOMAIN_SHADER,
			Mix::STR_RETERROR, Mix::STR_DEBUGNAME, MIX_SAFE_NAME( pDebugName ), Mix::STR_RESULT, GetD3DResultText( ret ) );

		return False;
	}

	pDomainShader = Mix::Graphics::DX11::DomainShader::CreateInstance( this, pD3DDomainShader );
	if( pDomainShader == NULL )
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s]", FAILED_CREATE_DOMAIN_SHADER,
			Mix::STR_OUTOFMEMORY, Mix::STR_DEBUGNAME, MIX_SAFE_NAME( pDebugName ) );

		MIX_RELEASE( pD3DDomainShader );

		return False;
	}

	( *ppDomainShader ) = pDomainShader;

	return True;
}

Boolean Device::CreateGeometryShaderFromFile( const wchar_t* pFilePath, Mix::Graphics::IGeometryShader** ppGeometryShader )
{
	if( ( pFilePath == NULL ) ||
		( ::wcslen( pFilePath ) == 0 ) ||
		( ppGeometryShader == NULL ) )
	{
		MIX_LOG_ERROR( L"%s : %s : pFilePath[%s] ppGeometryShader[%s]", FAILED_CREATE_GEOMETRY_SHADER,
			Mix::STR_ILLEGALARG,
			MIX_LOG_STR( pFilePath ),
			MIX_LOG_PTR( ppGeometryShader ) );

		return False;
	}

	HRESULT ret;
	Mix::Memory::IBuffer* pBuffer;
	ID3D11GeometryShader* pD3DGeometryShader;
	Mix::Graphics::DX11::GeometryShader* pGeometryShader;

	if( m_pFileMgr->CreateBufferFromFile( pFilePath, &pBuffer ) == False )
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s]", FAILED_CREATE_GEOMETRY_SHADER,
			Mix::STR_FILENOTFOUND, Mix::STR_FILEPATH, pFilePath );

		return False;
	}

	ret = m_pD3DDevice->CreateGeometryShader( pBuffer->GetConstPointer(), pBuffer->GetSize(), NULL, &pD3DGeometryShader );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : CreateGeometryShader %s : %s[%s] %s[%s]", FAILED_CREATE_GEOMETRY_SHADER,
			Mix::STR_RETERROR, Mix::STR_FILEPATH, pFilePath, Mix::STR_RESULT, GetD3DResultText( ret ) );

		MIX_RELEASE( pBuffer );

		return False;
	}

	pGeometryShader = Mix::Graphics::DX11::GeometryShader::CreateInstance( this, pD3DGeometryShader );
	if( pGeometryShader == NULL )
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s]", FAILED_CREATE_GEOMETRY_SHADER,
			Mix::STR_OUTOFMEMORY, Mix::STR_FILEPATH, pFilePath );

		MIX_RELEASE( pD3DGeometryShader );
		MIX_RELEASE( pBuffer );

		return False;
	}

	( *ppGeometryShader ) = pGeometryShader;

	return True;
}

Boolean Device::CreateGeometryShaderFromMemory( const void* pSrc, UInt32 srcSize, Mix::Graphics::IGeometryShader** ppGeometryShader, const wchar_t* pDebugName )
{
	if( ( pSrc == NULL ) ||
		( srcSize == 0 ) ||
		( ppGeometryShader == NULL ) )
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s] : pSrc[%s] srcSize[%d] ppGeometryShader[%s]", FAILED_CREATE_GEOMETRY_SHADER,
			Mix::STR_ILLEGALARG,
			Mix::STR_DEBUGNAME,
			MIX_SAFE_NAME( pDebugName ),
			MIX_LOG_PTR( pSrc ),
			srcSize,
			MIX_LOG_PTR( ppGeometryShader ) );

		return False;
	}

	HRESULT ret;
	ID3D11GeometryShader* pD3DGeometryShader;
	Mix::Graphics::DX11::GeometryShader* pGeometryShader;

	ret = m_pD3DDevice->CreateGeometryShader( pSrc, srcSize, NULL, &pD3DGeometryShader );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : CreateGeometryShader %s : %s[%s] %s[%s]", FAILED_CREATE_GEOMETRY_SHADER,
			Mix::STR_RETERROR, Mix::STR_DEBUGNAME, MIX_SAFE_NAME( pDebugName ), Mix::STR_RESULT, GetD3DResultText( ret ) );

		return False;
	}

	pGeometryShader = Mix::Graphics::DX11::GeometryShader::CreateInstance( this, pD3DGeometryShader );
	if( pGeometryShader == NULL )
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s]", FAILED_CREATE_GEOMETRY_SHADER,
			Mix::STR_OUTOFMEMORY, Mix::STR_DEBUGNAME, MIX_SAFE_NAME( pDebugName ) );

		MIX_RELEASE( pD3DGeometryShader );

		return False;
	}

	( *ppGeometryShader ) = pGeometryShader;

	return True;
}

Boolean Device::CreateVertexShaderFromFile( const wchar_t* pFilePath, Mix::Graphics::IVertexShader** ppVertexShader )
{
	if( ( pFilePath == NULL ) ||
		( ::wcslen( pFilePath ) == 0 ) ||
		( ppVertexShader == NULL ) )
	{
		MIX_LOG_ERROR( L"%s : %s : pFilePath[%s] ppVertexShader[%s]", FAILED_CREATE_VERTEX_SHADER,
			Mix::STR_ILLEGALARG,
			MIX_LOG_STR( pFilePath ),
			MIX_LOG_PTR( ppVertexShader ) );

		return False;
	}

	HRESULT ret;
	Mix::Memory::IBuffer* pBuffer;
	Mix::Graphics::DX11::VertexShader* pVertexShader;
	ID3D11VertexShader* pD3DVertexShader;

	if( m_pFileMgr->CreateBufferFromFile( pFilePath, &pBuffer ) == False )
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s]", FAILED_CREATE_VERTEX_SHADER,
			Mix::STR_FILENOTFOUND, Mix::STR_FILEPATH, pFilePath );

		return False;
	}

	ret = m_pD3DDevice->CreateVertexShader( pBuffer->GetConstPointer(), pBuffer->GetSize(), NULL, &pD3DVertexShader );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : CreateVertexShader %s : %s[%s] %s[%s]", FAILED_CREATE_VERTEX_SHADER,
			Mix::STR_RETERROR, Mix::STR_FILEPATH, pFilePath, Mix::STR_RESULT, GetD3DResultText( ret ) );

		MIX_RELEASE( pBuffer );

		return False;
	}

	pVertexShader = Mix::Graphics::DX11::VertexShader::CreateInstance( this, pD3DVertexShader, pBuffer );
	if( pVertexShader == NULL )
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s]", FAILED_CREATE_VERTEX_SHADER,
			Mix::STR_OUTOFMEMORY, Mix::STR_FILEPATH, pFilePath );

		MIX_RELEASE( pD3DVertexShader );
		MIX_RELEASE( pBuffer );

		return False;
	}

	( *ppVertexShader ) = pVertexShader;

	return True;
}

Boolean Device::CreateVertexShaderFromMemory( const void* pSrc, UInt32 srcSize, Mix::Graphics::IVertexShader** ppVertexShader, const wchar_t* pDebugName )
{
	if( ( pSrc == NULL ) ||
		( srcSize == 0 ) ||
		( ppVertexShader == NULL ) )
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s] : pSrc[%s] srcSize[%d] ppVertexShader[%s]", FAILED_CREATE_VERTEX_SHADER,
			Mix::STR_ILLEGALARG,
			Mix::STR_DEBUGNAME,
			MIX_SAFE_NAME( pDebugName ),
			MIX_LOG_PTR( pSrc ),
			srcSize,
			MIX_LOG_PTR( ppVertexShader ) );

		return False;
	}

	HRESULT ret;
	Mix::Memory::Buffer* pBuffer;
	ID3D11VertexShader* pD3DVertexShader;
	Mix::Graphics::DX11::VertexShader* pVertexShader;

	pBuffer = Mix::Memory::Buffer::CreateInstance();
	if( ( pBuffer != NULL ) && ( pBuffer->Create( Mix::Memory::SECTION_GRAPHICS, srcSize ) == True ) ) 
	{
		Mix::Memory::Copy( pBuffer->GetPointer(), pSrc, srcSize );
	}
	else
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s]", FAILED_CREATE_VERTEX_SHADER,
			Mix::STR_OUTOFMEMORY, Mix::STR_DEBUGNAME, MIX_SAFE_NAME( pDebugName ) );

		MIX_RELEASE( pBuffer );

		return False;
	}
	
	ret = m_pD3DDevice->CreateVertexShader( pBuffer->GetConstPointer(), pBuffer->GetSize(), NULL, &pD3DVertexShader );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : CreateVertexShader %s : %s[%s] %s[%s]", FAILED_CREATE_VERTEX_SHADER,
			Mix::STR_RETERROR, Mix::STR_DEBUGNAME, MIX_SAFE_NAME( pDebugName ), Mix::STR_RESULT, GetD3DResultText( ret ) );

		MIX_RELEASE( pBuffer );

		return False;
	}

	pVertexShader = Mix::Graphics::DX11::VertexShader::CreateInstance( this, pD3DVertexShader, pBuffer );
	if( pVertexShader == NULL )
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s]", FAILED_CREATE_VERTEX_SHADER,
			Mix::STR_OUTOFMEMORY, Mix::STR_DEBUGNAME, MIX_SAFE_NAME( pDebugName ) );

		MIX_RELEASE( pD3DVertexShader );
		MIX_RELEASE( pBuffer );

		return False;
	}

	( *ppVertexShader ) = pVertexShader;

	return True;
}

Boolean Device::CreatePixelShaderFromFile( const wchar_t* pFilePath, Mix::Graphics::IPixelShader** ppPixelShader )
{
	if( ( pFilePath == NULL ) ||
		( ::wcslen( pFilePath ) == 0 ) ||
		( ppPixelShader == NULL ) )
	{
		MIX_LOG_ERROR( L"%s : %s : pFileName[%s] ppPixelShader[%s]", FAILED_CREATE_PIXEL_SHADER,
			Mix::STR_ILLEGALARG,
			MIX_LOG_STR( pFilePath ),
			MIX_LOG_PTR( ppPixelShader ) );

		return False;
	}

	HRESULT ret;
	Mix::Memory::IBuffer* pBuffer;
	Mix::Graphics::DX11::PixelShader* pPixelShader;
	ID3D11PixelShader* pD3DPixelShader;

	if( m_pFileMgr->CreateBufferFromFile( pFilePath, &pBuffer ) == False )
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s]", FAILED_CREATE_PIXEL_SHADER,
			Mix::STR_FILENOTFOUND, Mix::STR_FILEPATH, pFilePath );

		return False;
	}

	ret = m_pD3DDevice->CreatePixelShader( pBuffer->GetConstPointer(), pBuffer->GetSize(), NULL, &pD3DPixelShader );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : CreatePixelShader %s : %s[%s] %s[%s]", FAILED_CREATE_PIXEL_SHADER,
			Mix::STR_RETERROR, Mix::STR_FILEPATH, pFilePath, Mix::STR_RESULT, GetD3DResultText( ret ) );

		MIX_RELEASE( pBuffer );

		return False;
	}

	MIX_RELEASE( pBuffer );

	pPixelShader = Mix::Graphics::DX11::PixelShader::CreateInstance( this, pD3DPixelShader );
	if( pPixelShader == NULL )
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s]", FAILED_CREATE_PIXEL_SHADER,
			Mix::STR_OUTOFMEMORY, Mix::STR_FILEPATH, pFilePath );

		MIX_RELEASE( pD3DPixelShader );

		return False;
	}

	( *ppPixelShader ) = pPixelShader;

	return True;
}

Boolean Device::CreatePixelShaderFromMemory( const void* pSrc, UInt32 srcSize, Mix::Graphics::IPixelShader** ppPixelShader, const wchar_t* pDebugName )
{
	if( ( pSrc == NULL ) ||
		( srcSize == 0 ) ||
		( ppPixelShader == NULL ) )
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s] : pSrc[%s] srcSize[%d] ppPixelShader[%s]", FAILED_CREATE_PIXEL_SHADER,
			Mix::STR_ILLEGALARG,
			Mix::STR_DEBUGNAME,
			MIX_SAFE_NAME( pDebugName ),
			MIX_LOG_PTR( pSrc ),
			srcSize,
			MIX_LOG_PTR( ppPixelShader ) );

		return False;
	}

	HRESULT ret;
	Mix::Graphics::DX11::PixelShader* pPixelShader;
	ID3D11PixelShader* pD3DPixelShader;

	ret = m_pD3DDevice->CreatePixelShader( pSrc, srcSize, NULL, &pD3DPixelShader );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : CreatePixelShader %s : %s[%s] %s[%s]", FAILED_CREATE_PIXEL_SHADER,
			Mix::STR_RETERROR, Mix::STR_DEBUGNAME, MIX_SAFE_NAME( pDebugName ), Mix::STR_RESULT, GetD3DResultText( ret ) );

		return False;
	}

	pPixelShader = Mix::Graphics::DX11::PixelShader::CreateInstance( this, pD3DPixelShader );
	if( pPixelShader == NULL )
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s]", FAILED_CREATE_PIXEL_SHADER,
			Mix::STR_OUTOFMEMORY, Mix::STR_DEBUGNAME, MIX_SAFE_NAME( pDebugName ) );

		MIX_RELEASE( pD3DPixelShader );

		return False;
	}

	( *ppPixelShader ) = pPixelShader;

	return True;
}

Boolean Device::CreateShaderConstant( UInt32 size, Boolean bDynamic, const void* pInitialData, Mix::Graphics::IShaderConstant** ppShaderConstant, const wchar_t* pDebugName )
{
	if( ( size == 0 ) ||
		( ppShaderConstant == NULL ) )
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s] : size[%d] ppShaderConstant[%s]", FAILED_CREATE_SHADER_CONSTANT,
			Mix::STR_ILLEGALARG,
			Mix::STR_DEBUGNAME,
			MIX_SAFE_NAME( pDebugName ),
			size,
			MIX_LOG_PTR( ppShaderConstant ) );

		return False;
	}

	HRESULT ret;
	UInt32 bufferSize;
	D3D11_BUFFER_DESC desc;
	ID3D11Buffer* pD3DBuffer;
	Mix::Graphics::DX11::ShaderConstant* pShaderConstant;

	bufferSize = ( size / 16 ) * 16;
	if( ( size % 16 ) > 0 )
	{
		bufferSize += 16;
	}

	desc.ByteWidth = bufferSize;
	desc.Usage = ( bDynamic == True )? D3D11_USAGE_DYNAMIC : D3D11_USAGE_DEFAULT;
	desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
	desc.CPUAccessFlags = ( bDynamic == True )? D3D11_CPU_ACCESS_WRITE : 0;
	desc.MiscFlags = 0;
	desc.StructureByteStride = 0;

	if( pInitialData != NULL )
	{
		D3D11_SUBRESOURCE_DATA data;

		data.pSysMem = pInitialData;
		data.SysMemPitch = 0;
		data.SysMemSlicePitch = 0;

		ret = m_pD3DDevice->CreateBuffer( &desc, &data, &pD3DBuffer );
	}
	else
	{
		ret = m_pD3DDevice->CreateBuffer( &desc, NULL, &pD3DBuffer );
	}

	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : CreateBuffer %s : %s[%s] %s[%s]", FAILED_CREATE_SHADER_CONSTANT,
			Mix::STR_RETERROR, Mix::STR_DEBUGNAME, MIX_SAFE_NAME( pDebugName ), Mix::STR_RESULT, GetD3DResultText( ret ) );

		return False;
	}

	pShaderConstant = Mix::Graphics::DX11::ShaderConstant::CreateInstance( this, bufferSize, bDynamic, pD3DBuffer );
	if( pShaderConstant == NULL )
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s]", FAILED_CREATE_SHADER_CONSTANT,
			Mix::STR_OUTOFMEMORY, Mix::STR_DEBUGNAME, MIX_SAFE_NAME( pDebugName ) );

		MIX_RELEASE( pD3DBuffer );

		return False;
	}

	( *ppShaderConstant ) = pShaderConstant;

	return True;
}

Boolean Device::CreateVertexLayout( const Mix::Graphics::VERTEX_ELEMENT* pElements, UInt32 elementCount, const Mix::Graphics::IVertexShader* pVertexShader, Mix::Graphics::IVertexLayout** ppVertexLayout, const wchar_t* pDebugName )
{
	if( ( pElements == NULL ) ||
		( elementCount == 0 ) ||
		( pVertexShader == NULL ) ||
		( ppVertexLayout == NULL ) )
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s] : pElements[%s] elementCount[%d] pVertexShader[%s] ppVertexLayout[%s]",
			FAILED_CREATE_VERTEX_LAYOUT,
			Mix::STR_ILLEGALARG,
			Mix::STR_DEBUGNAME,
			MIX_SAFE_NAME( pDebugName ),
			MIX_LOG_PTR( pElements ),
			elementCount,
			MIX_LOG_PTR( pVertexShader ),
			MIX_LOG_PTR( pVertexShader ) );

		return False;
	}

	HRESULT ret;
	UInt32 i;
	UInt32 stride;
	D3D11_INPUT_ELEMENT_DESC* pD3DElements;
	ID3D11InputLayout* pD3DVertexLayout;
	const Mix::Graphics::DX11::VertexShader* pCompVS;
	Mix::Graphics::DX11::VertexLayout* pVertexLayout;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// バーテックスレイアウトを作成
	////////////////////////////////////////////////////////////////////////////////////////////////////

	stride = 0;

	pD3DElements = static_cast<D3D11_INPUT_ELEMENT_DESC*>( MIX_LIB_MALLOC( Mix::Memory::SECTION_GRAPHICS, sizeof( D3D11_INPUT_ELEMENT_DESC ) * elementCount ) );
	if( pD3DElements == NULL )
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s]", FAILED_CREATE_VERTEX_LAYOUT,
			Mix::STR_OUTOFMEMORY, Mix::STR_DEBUGNAME, MIX_SAFE_NAME( pDebugName ) );
		return False;
	}

	for( i = 0; i < elementCount; i++ )
	{
		UInt32 format = pElements[i].format;

		pD3DElements[i].SemanticName = D3DVLSemanticTable[pElements[i].semanticType];
		pD3DElements[i].SemanticIndex = pElements[i].semanticIndex;
		pD3DElements[i].Format = Device::D3DVLFormatTable[format];
		pD3DElements[i].InputSlot = 0;
		pD3DElements[i].AlignedByteOffset = pElements[i].offset;
		pD3DElements[i].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
		pD3DElements[i].InstanceDataStepRate = 0;

		stride += Device::GetVertexElementSize( format );
	}

	pCompVS = dynamic_cast<const Mix::Graphics::DX11::VertexShader*>( pVertexShader );

	ret = m_pD3DDevice->CreateInputLayout( pD3DElements, elementCount, pCompVS->GetInputSignature(), pCompVS->GetInputSignatureSize(), &pD3DVertexLayout );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : CreateInputLayout %s : %s[%s] Result[%s]", FAILED_CREATE_VERTEX_LAYOUT,
			Mix::STR_RETERROR, Mix::STR_DEBUGNAME, MIX_SAFE_NAME( pDebugName ), Mix::STR_RESULT, GetD3DResultText( ret ) );

		MIX_LIB_FREE( pD3DElements );

		return False;
	}

	MIX_LIB_FREE( pD3DElements );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// インターフェースを作成
	////////////////////////////////////////////////////////////////////////////////////////////////////

	pVertexLayout = Mix::Graphics::DX11::VertexLayout::CreateInstance(	this,
																		pD3DVertexLayout,
																		pElements,
																		elementCount,
																		stride );
	if( pVertexLayout == NULL )
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s]", FAILED_CREATE_VERTEX_LAYOUT,
			Mix::STR_OUTOFMEMORY, Mix::STR_DEBUGNAME, MIX_SAFE_NAME( pDebugName ) );

		MIX_RELEASE( pD3DVertexLayout );

		return False;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 譲渡
	////////////////////////////////////////////////////////////////////////////////////////////////////

	( *ppVertexLayout ) = pVertexLayout;

	////////////////////////////////////////////////////////////////////////////////////////////////////

	return True;
}

Boolean Device::CreateVertexBuffer( UInt32 count, UInt32 stride, Boolean bDynamic, UInt32 resizeStep, const void* pInitialData, Mix::Graphics::IVertexBuffer** ppVertexBuffer, const wchar_t* pDebugName )
{
	if( ( count == 0 ) ||
		( stride == 0 ) ||
		( ppVertexBuffer == NULL ) )
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s] : count[%d] stride[%d] ppVertexBuffer[%s]", FAILED_CREATE_VERTEX_BUFFER,
			Mix::STR_ILLEGALARG,
			MIX_SAFE_NAME( pDebugName ),
			count,
			stride,
			MIX_LOG_PTR( ppVertexBuffer ) );

		return False;
	}

	HRESULT ret;
	Mix::Graphics::DX11::VertexBuffer* pVertexBuffer;

	pVertexBuffer = Mix::Graphics::DX11::VertexBuffer::CreateInstance( this, count, stride, bDynamic, resizeStep );
	if( pVertexBuffer == NULL )
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s]", FAILED_CREATE_VERTEX_BUFFER,
			Mix::STR_OUTOFMEMORY, Mix::STR_DEBUGNAME, MIX_SAFE_NAME( pDebugName ) );

		return False;
	}

	ret = pVertexBuffer->Initialize( pInitialData );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : Initialize %s : %s[%s] %s[%s]", FAILED_CREATE_VERTEX_BUFFER,
			Mix::STR_RETERROR, Mix::STR_DEBUGNAME, MIX_SAFE_NAME( pDebugName ), Mix::STR_RESULT, GetD3DResultText( ret ) );

		MIX_RELEASE( pVertexBuffer );

		return False;
	}

#ifdef _DEBUG
	pVertexBuffer->SetDebugName( MIX_SAFE_NAME( pDebugName ) );
#endif //_DEBUG

	( *ppVertexBuffer ) = pVertexBuffer;

	return True;
}

Boolean Device::CreateIndexBuffer( Mix::Graphics::INDEX_FORMAT format, UInt32 count, Boolean bDynamic, UInt32 resizeStep, const void* pInitialData, Mix::Graphics::IIndexBuffer** ppIndexBuffer, const wchar_t* pDebugName )
{
	if( ( count == 0 ) ||
		( ppIndexBuffer == NULL ) )
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s] : count[%d] pIndexBuffer[%s]", FAILED_CREATE_INDEX_BUFFER,
			Mix::STR_ILLEGALARG,
			Mix::STR_DEBUGNAME,
			MIX_SAFE_NAME( pDebugName ),
			count,
			MIX_LOG_PTR( ppIndexBuffer ) );

		return False;
	}

	HRESULT ret;
	Mix::Graphics::DX11::IndexBuffer* pIndexBuffer;

	if( m_IndexTypeSupportList[format] == False )
	{
		MIX_LOG_ERROR( L"%s : 指定されたインデックスタイプはサポートされていません : %s[%s] %s[%s]", FAILED_CREATE_INDEX_BUFFER,
			Mix::STR_DEBUGNAME,
			MIX_SAFE_NAME( pDebugName ),
			Mix::STR_FORMAT,
			D3DIndexFormatTextTable[format] );

		return False;
	}

	pIndexBuffer = Mix::Graphics::DX11::IndexBuffer::CreateInstance( this, format, count, bDynamic, resizeStep );
	if( pIndexBuffer == NULL )
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s]", FAILED_CREATE_INDEX_BUFFER,
			Mix::STR_OUTOFMEMORY, Mix::STR_DEBUGNAME, MIX_SAFE_NAME( pDebugName ) );

		return False;
	}

	ret = pIndexBuffer->Initialize( pInitialData );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : Initialize %s : %s[%s] %s[%s]", FAILED_CREATE_INDEX_BUFFER,
			Mix::STR_RETERROR, Mix::STR_DEBUGNAME, MIX_SAFE_NAME( pDebugName ), Mix::STR_RESULT, GetD3DResultText( ret ) );

		MIX_RELEASE( pIndexBuffer );

		return False;
	}

#ifdef _DEBUG
	pIndexBuffer->SetDebugName( MIX_SAFE_NAME( pDebugName ) );
#endif //_DEBUG

	( *ppIndexBuffer ) = pIndexBuffer;

	return True;
}

Boolean Device::CreateTextureFromFile( const wchar_t* pFilePath, Mix::Graphics::ITexture** ppTexture )
{
	if( ( pFilePath == NULL ) ||
		( ::wcslen( pFilePath ) == 0 ) ||
		( ppTexture == NULL ) )
	{
		MIX_LOG_ERROR( L"%s : %s : pFilePath[%s] ppTexture[%s]", FAILED_CREATE_TEXTURE,
			Mix::STR_ILLEGALARG,
			MIX_LOG_STR( pFilePath ),
			MIX_LOG_PTR( ppTexture ) );

		return False;
	}

	Mix::Memory::IBuffer* pBuffer = NULL;
	Mix::Graphics::ITexture* pTexture = NULL;

	if( m_pFileMgr->CreateBufferFromFile( pFilePath, &pBuffer ) == False )
	{
		return False;
	}

	pTexture = CreateTextureFromPlugin( pFilePath, pBuffer->GetConstPointer(), MIX_UIT_TO_UI32( pBuffer->GetSize() ) );
	if( pTexture == NULL )
	{
		MIX_RELEASE( pBuffer );
		return False;
	}

	MIX_RELEASE( pBuffer );

	( *ppTexture ) = pTexture;

	return True;
}

Boolean Device::CreateTextureFromMemory( const wchar_t* pFilePath, const void* pSrc, UInt32 srcSize, Mix::Graphics::ITexture** ppTexture )
{
	if( ( pFilePath == NULL ) || ( wcslen( pFilePath ) == 0 ) ||
		( pSrc == NULL ) || ( srcSize == 0 ) ||
		( ppTexture == NULL ) )
	{
		MIX_LOG_ERROR( L"%s : %s : pFilePath[%s] pSrc[%s] srcSize[%d] ppTexture[%s]", FAILED_CREATE_TEXTURE,
			Mix::STR_ILLEGALARG,
			MIX_LOG_STR( pFilePath ),
			MIX_LOG_PTR( pSrc ), 
			srcSize,
			MIX_LOG_PTR( ppTexture ) );

		return False;
	}

	Mix::Graphics::ITexture* pTexture = NULL;

	pTexture = CreateTextureFromPlugin( pFilePath, pSrc, srcSize );
	if( pTexture == NULL )
	{
		return False;
	}

	( *ppTexture ) = pTexture;

	return True;
}

Boolean Device::CreateDynamicPlaneTexture( UInt32 width, UInt32 height, Mix::Graphics::FORMAT format, Mix::Graphics::ITexture** ppTexture, const wchar_t* pDebugName )
{
	if( ( width == 0 ) ||
		( height == 0 ) ||
		( ppTexture == NULL ) )
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s] : width[%d] height[%d] format[%s] ppTexture[%s]", FAILED_CREATE_TEXTURE_DYNAMIC_PLANE,
			Mix::STR_ILLEGALARG,
			Mix::STR_DEBUGNAME,
			MIX_SAFE_NAME( pDebugName ),
			width,
			height,
			GetFormatText( format ),
			MIX_LOG_PTR( ppTexture ) );

		return False;
	}

	HRESULT ret;
	D3D11_TEXTURE2D_DESC desc;
	ID3D11Texture2D* pD3DTexture;
	ID3D11ShaderResourceView* pD3DView;
	Mix::Graphics::DX11::TextureDynamic* pTexture;

	if( IsDynamicPlaneTextureSupported( format ) == False )
	{
		MIX_LOG_ERROR( L"%s : サポートされないフォーマット : %s[%s] %s[%s]", FAILED_CREATE_TEXTURE_DYNAMIC_PLANE,
			Mix::STR_DEBUGNAME, MIX_SAFE_NAME( pDebugName ), Mix::STR_FORMAT, GetFormatText( format ) );

		return False;
	}

	desc.Width = width;
	desc.Height = height;
	desc.MipLevels = 1;
	desc.ArraySize = 1;
	desc.Format = m_ResourceFmtList[format].format;
	desc.SampleDesc.Count = 1;
	desc.SampleDesc.Quality = 0;
	desc.Usage = D3D11_USAGE_DYNAMIC;
	desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
	desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
	desc.MiscFlags = 0;

	ret = m_pD3DDevice->CreateTexture2D( &desc, NULL, &pD3DTexture );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : CreateTexture2D %s : %s[%s] %s[%s]", FAILED_CREATE_TEXTURE_DYNAMIC_PLANE,
			Mix::STR_RETERROR, Mix::STR_DEBUGNAME, MIX_SAFE_NAME( pDebugName ), Mix::STR_RESULT, GetD3DResultText( ret ) );

		return False;
	}

	ret = m_pD3DDevice->CreateShaderResourceView( pD3DTexture, NULL, &pD3DView );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : CreateShaderResourceView %s : %s[%s] %s[%s]", FAILED_CREATE_TEXTURE_DYNAMIC_PLANE,
			Mix::STR_RETERROR, Mix::STR_DEBUGNAME, MIX_SAFE_NAME( pDebugName ), Mix::STR_RESULT, GetD3DResultText( ret ) );

		MIX_RELEASE( pD3DTexture );

		return False;
	}

	pTexture = Mix::Graphics::DX11::TextureDynamic::CreateInstance(	this,
																	width, height, Device::ConvertTextureFormat( desc.Format ),
																	pD3DTexture, pD3DView );
	if( pTexture == NULL )
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s]", FAILED_CREATE_TEXTURE_DYNAMIC_PLANE,
			Mix::STR_OUTOFMEMORY, Mix::STR_DEBUGNAME, MIX_SAFE_NAME( pDebugName ) );

		MIX_RELEASE( pD3DView );
		MIX_RELEASE( pD3DTexture );

		return False;
	}

	( *ppTexture ) = pTexture;

	return True;
}

Boolean Device::CreateTargetPlaneTexture( UInt32 width, UInt32 height, Mix::Graphics::FORMAT format, Mix::Graphics::ITexture** ppTexture, const wchar_t* pDebugName )
{
	if( ( width == 0 ) ||
		( height == 0 ) ||
		( ppTexture == NULL ) )
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s] : width[%d] height[%d] format[%s] ppTexture[%s]", FAILED_CREATE_TEXTURE_TARGET_PLANE,
			Mix::STR_ILLEGALARG,
			Mix::STR_DEBUGNAME,
			MIX_SAFE_NAME( pDebugName ),
			width,
			height,
			GetFormatText( format ),
			MIX_LOG_PTR( ppTexture ) );

		return False;
	}

	HRESULT ret;
	D3D11_TEXTURE2D_DESC desc;
	D3D11_RENDER_TARGET_VIEW_DESC rtDesc;
	D3D11_SHADER_RESOURCE_VIEW_DESC srDesc;
	ID3D11Texture2D* pD3DTexture;
	ID3D11RenderTargetView* pD3DRTView;
	ID3D11ShaderResourceView* pD3DSRView;
	Mix::Graphics::DX11::TextureTarget* pTexture;

	if( IsTargetPlaneTextureSupported( format ) == False )
	{
		MIX_LOG_ERROR( L"%s : サポートされないフォーマット : %s[%s] %s[%s]", FAILED_CREATE_TEXTURE_TARGET_PLANE,
			Mix::STR_DEBUGNAME, MIX_SAFE_NAME( pDebugName ), Mix::STR_FORMAT, GetFormatText( format ) );

		return False;
	}

	desc.Width = width;
	desc.Height = height;
	desc.MipLevels = 1;
	desc.ArraySize = 1;
	desc.Format = m_ResourceFmtList[format].format;
	desc.SampleDesc.Count = 1;
	desc.SampleDesc.Quality = 0;
	desc.Usage = D3D11_USAGE_DEFAULT;
	desc.BindFlags = ( D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET );
	desc.CPUAccessFlags = 0;
	desc.MiscFlags = 0;

	ret = m_pD3DDevice->CreateTexture2D( &desc, NULL, &pD3DTexture );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : CreateTexture2D %s : %s[%s] %s[%s]", FAILED_CREATE_TEXTURE_TARGET_PLANE,
			Mix::STR_RETERROR, Mix::STR_DEBUGNAME, MIX_SAFE_NAME( pDebugName ), Mix::STR_RESULT, GetD3DResultText( ret ) );

		return False;
	}

	rtDesc.Format = m_ResourceFmtList[format].format;
	rtDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
	rtDesc.Texture2D.MipSlice = 0;

	ret = m_pD3DDevice->CreateRenderTargetView( pD3DTexture, &rtDesc, &pD3DRTView );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : CreateRenderTargetView %s : %s[%s] %s[%s]", FAILED_CREATE_TEXTURE_TARGET_PLANE,
			Mix::STR_RETERROR, Mix::STR_DEBUGNAME, MIX_SAFE_NAME( pDebugName ), Mix::STR_RESULT, GetD3DResultText( ret ) );

		MIX_RELEASE( pD3DTexture );

		return False;
	}

	srDesc.Format = m_ResourceFmtList[format].format;
	srDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
	srDesc.Texture2D.MostDetailedMip = 0;
	srDesc.Texture2D.MipLevels = 1;

	ret = m_pD3DDevice->CreateShaderResourceView( pD3DTexture, &srDesc, &pD3DSRView );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : CreateShaderResourceView %s : %s[%s] %s[%s]", FAILED_CREATE_TEXTURE_TARGET_PLANE,
			Mix::STR_RETERROR, Mix::STR_DEBUGNAME, MIX_SAFE_NAME( pDebugName ), Mix::STR_RESULT, GetD3DResultText( ret ) );

		MIX_RELEASE( pD3DRTView );
		MIX_RELEASE( pD3DTexture );

		return False;
	}

	pTexture = Mix::Graphics::DX11::TextureTarget::CreateInstance(	this,
																	width, height, format,
																	pD3DTexture, pD3DRTView, pD3DSRView );
	if( pTexture != NULL )
	{
		( *ppTexture ) = pTexture;
	}
	else
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s]", FAILED_CREATE_TEXTURE_TARGET_PLANE,
			Mix::STR_OUTOFMEMORY, Mix::STR_DEBUGNAME, MIX_SAFE_NAME( pDebugName ) );

		MIX_RELEASE( pD3DRTView );
		MIX_RELEASE( pD3DSRView );
		MIX_RELEASE( pD3DTexture );

		return False;
	}

	return True;
}

Boolean Device::CreateLockableTargetPlaneTexture( UInt32 width, UInt32 height, Mix::Graphics::FORMAT format, Mix::Graphics::ITexture** ppTexture, const wchar_t* pDebugName )
{
	if( ( width == 0 ) ||
		( height == 0 ) ||
		( ppTexture == NULL ) )
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s] : width[%d] height[%d] format[%s] ppTexture[%s]", FAILED_CREATE_TEXTURE_LOCKABLE_TARGET_PLANE,
			Mix::STR_ILLEGALARG,
			Mix::STR_DEBUGNAME,
			MIX_SAFE_NAME( pDebugName ),
			width,
			height,
			GetFormatText( format ),
			MIX_LOG_PTR( ppTexture ) );

		return False;
	}

	HRESULT ret;
	D3D11_TEXTURE2D_DESC desc;
	D3D11_RENDER_TARGET_VIEW_DESC rtDesc;
	D3D11_SHADER_RESOURCE_VIEW_DESC srDesc;
	ID3D11Texture2D* pD3DTexture;
	ID3D11Texture2D* pD3DReadingTexture;
	ID3D11RenderTargetView* pD3DRTView;
	ID3D11ShaderResourceView* pD3DSRView;
	Mix::Graphics::DX11::TextureTargetL* pTexture;

	if( IsLockableTargetPlaneTextureSupported( format ) == False )
	{
		MIX_LOG_ERROR( L"%s : サポートされないフォーマット : %s[%s] %s[%s]", FAILED_CREATE_TEXTURE_LOCKABLE_TARGET_PLANE,
			Mix::STR_DEBUGNAME, MIX_SAFE_NAME( pDebugName ), Mix::STR_FORMAT, GetFormatText( format ) );

		return False;
	}

	// テクスチャの共通設定

	desc.Width = width;
	desc.Height = height;
	desc.MipLevels = 1;
	desc.ArraySize = 1;
	desc.Format = m_ResourceFmtList[format].format;
	desc.SampleDesc.Count = 1;
	desc.SampleDesc.Quality = 0;
	desc.MiscFlags = 0;

	// GPU による読み書き可能なテクスチャの作成

	desc.Usage = D3D11_USAGE_DEFAULT;
	desc.BindFlags = ( D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET );
	desc.CPUAccessFlags = 0;

	ret = m_pD3DDevice->CreateTexture2D( &desc, NULL, &pD3DTexture );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : CreateTexture2D %s : %s[%s] %s[%s]", FAILED_CREATE_TEXTURE_LOCKABLE_TARGET_PLANE,
			Mix::STR_RETERROR, Mix::STR_DEBUGNAME, MIX_SAFE_NAME( pDebugName ), Mix::STR_RESULT, GetD3DResultText( ret ) );

		return False;
	}

	// ロックして読み取るためのテクスチャの作成

	desc.Usage = D3D11_USAGE_STAGING;
	desc.BindFlags = 0;
	desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;

	ret = m_pD3DDevice->CreateTexture2D( &desc, NULL, &pD3DReadingTexture );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : CreateTexture2D %s : %s[%s] %s[%s]", FAILED_CREATE_TEXTURE_LOCKABLE_TARGET_PLANE,
			Mix::STR_RETERROR, Mix::STR_DEBUGNAME, MIX_SAFE_NAME( pDebugName ), Mix::STR_RESULT, GetD3DResultText( ret ) );

		return False;
	}

	// レンダーターゲットビューの作成

	rtDesc.Format = m_ResourceFmtList[format].format;
	rtDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
	rtDesc.Texture2D.MipSlice = 0;

	ret = m_pD3DDevice->CreateRenderTargetView( pD3DTexture, &rtDesc, &pD3DRTView );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : CreateRenderTargetView %s : %s[%s] %s[%s]", FAILED_CREATE_TEXTURE_LOCKABLE_TARGET_PLANE,
			Mix::STR_RETERROR, Mix::STR_DEBUGNAME, MIX_SAFE_NAME( pDebugName ), Mix::STR_RESULT, GetD3DResultText( ret ) );

		MIX_RELEASE( pD3DTexture );

		return False;
	}

	// シェーダーリソースビューの作成

	srDesc.Format = m_ResourceFmtList[format].format;
	srDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
	srDesc.Texture2D.MostDetailedMip = 0;
	srDesc.Texture2D.MipLevels = 1;

	ret = m_pD3DDevice->CreateShaderResourceView( pD3DTexture, &srDesc, &pD3DSRView );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : CreateShaderResourceView %s : %s[%s] %s[%s]", FAILED_CREATE_TEXTURE_LOCKABLE_TARGET_PLANE,
			Mix::STR_RETERROR, Mix::STR_DEBUGNAME, MIX_SAFE_NAME( pDebugName ), Mix::STR_RESULT, GetD3DResultText( ret ) );

		MIX_RELEASE( pD3DRTView );
		MIX_RELEASE( pD3DTexture );

		return False;
	}

	// インターフェースの作成

	pTexture = Mix::Graphics::DX11::TextureTargetL::CreateInstance(	this,
																	width, height, format,
																	pD3DTexture, pD3DReadingTexture, pD3DRTView, pD3DSRView );
	if( pTexture == NULL )
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s]", FAILED_CREATE_TEXTURE_LOCKABLE_TARGET_PLANE,
			Mix::STR_OUTOFMEMORY, Mix::STR_DEBUGNAME, MIX_SAFE_NAME( pDebugName ) );

		MIX_RELEASE( pD3DRTView );
		MIX_RELEASE( pD3DSRView );
		MIX_RELEASE( pD3DTexture );

		return False;
	}

	( *ppTexture ) = pTexture;

	return True;
}

Boolean Device::CreateTargetCubeTexture( UInt32 edgeLength, Mix::Graphics::FORMAT format, Mix::Graphics::ITexture** ppTexture, const wchar_t* pDebugName )
{
	if( ( edgeLength == 0 ) ||
		( ppTexture == NULL ) )
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s] : edgeLength[%d] ppTexture[%s]", FAILED_CREATE_TEXTURE_TARGET_CUBE,
			Mix::STR_ILLEGALARG,
			Mix::STR_DEBUGNAME,
			MIX_SAFE_NAME( pDebugName ),
			edgeLength,
			MIX_LOG_PTR( ppTexture ) );

		return False;
	}

	HRESULT ret;
	D3D11_TEXTURE2D_DESC desc;
	D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
	D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
	ID3D11Texture2D* pD3DTexture;
	ID3D11RenderTargetView* pD3DRTView;
	ID3D11ShaderResourceView* pD3DSRView;
	Mix::Graphics::DX11::TextureCube* pTexture;

	if( IsTargetCubeTextureSupported( format ) == False )
	{
		MIX_LOG_ERROR( L"%s : サポートされないフォーマット : %s[%s] %s[%s]", FAILED_CREATE_TEXTURE_TARGET_CUBE,
			Mix::STR_DEBUGNAME, MIX_SAFE_NAME( pDebugName ), Mix::STR_FORMAT, GetFormatText( format ) );

		return False;
	}

	desc.Width = edgeLength;
	desc.Height = edgeLength;
	desc.MipLevels = 1;
	desc.ArraySize = Mix::Graphics::CUBEMAP_FACE_MAX;
	desc.Format = m_ResourceFmtList[format].format;
	desc.SampleDesc.Count = 1;
	desc.SampleDesc.Quality = 0;
	desc.Usage = D3D11_USAGE_DEFAULT;
	desc.BindFlags = ( D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET );
	desc.CPUAccessFlags = 0;
	desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;

	ret = m_pD3DDevice->CreateTexture2D( &desc, NULL, &pD3DTexture );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : CreateTexture2D %s : %s[%s] %s[%s]", FAILED_CREATE_TEXTURE_TARGET_CUBE,
			Mix::STR_RETERROR, Mix::STR_DEBUGNAME, MIX_SAFE_NAME( pDebugName ), Mix::STR_RESULT, GetD3DResultText( ret ) );

		return False;
	}

	srvDesc.Format = m_ResourceFmtList[format].format;
	srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
	srvDesc.TextureCube.MostDetailedMip	= 0;
	srvDesc.TextureCube.MipLevels = desc.MipLevels;

	ret = m_pD3DDevice->CreateShaderResourceView( pD3DTexture, &srvDesc, &pD3DSRView );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : CreateShaderResourceView %s : %s[%s] %s[%s]", FAILED_CREATE_TEXTURE_TARGET_CUBE,
			Mix::STR_RETERROR, Mix::STR_DEBUGNAME, MIX_SAFE_NAME( pDebugName ), Mix::STR_RESULT, GetD3DResultText( ret ) );

		MIX_RELEASE( pD3DTexture );

		return False;
	}

	rtvDesc.Format = m_ResourceFmtList[format].format;
	rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
	rtvDesc.Texture2DArray.MipSlice = 0;
	rtvDesc.Texture2DArray.FirstArraySlice = 0;
	rtvDesc.Texture2DArray.ArraySize = Mix::Graphics::CUBEMAP_FACE_MAX;

	ret = m_pD3DDevice->CreateRenderTargetView( pD3DTexture, &rtvDesc, &pD3DRTView );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : CreateRenderTargetView %s : %s[%s] %s[%s]", FAILED_CREATE_TEXTURE_TARGET_CUBE,
			Mix::STR_RETERROR, Mix::STR_DEBUGNAME, MIX_SAFE_NAME( pDebugName ), Mix::STR_RESULT, GetD3DResultText( ret ) );

		MIX_RELEASE( pD3DTexture );

		return False;
	}

	pTexture = Mix::Graphics::DX11::TextureCube::CreateInstance(	this,
																	NULL,
																	edgeLength, edgeLength, Device::ConvertTextureFormat( desc.Format ),
																	pD3DTexture, pD3DSRView, pD3DRTView );
	if( pTexture == NULL )
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s]", FAILED_CREATE_TEXTURE_TARGET_CUBE,
			Mix::STR_OUTOFMEMORY, Mix::STR_DEBUGNAME, MIX_SAFE_NAME( pDebugName ) );

		MIX_RELEASE( pD3DSRView );
		MIX_RELEASE( pD3DTexture );

		return False;
	}

	( *ppTexture ) = pTexture;

	return True;
}

Boolean Device::CreateDepthTexture( UInt32 width, UInt32 height, Mix::Graphics::FORMAT format, Mix::Graphics::ITexture** ppTexture, const wchar_t* pDebugName )
{
	if( ( width == 0 ) ||
		( height == 0 ) ||
		( ppTexture == NULL ) )
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s] : width[%d] height[%d] format[%d] ppTexture[%s]", FAILED_CREATE_TEXTURE_DEPTH,
			Mix::STR_ILLEGALARG,
			Mix::STR_DEBUGNAME,
			MIX_SAFE_NAME( pDebugName ),
			width,
			height,
			GetFormatText( format ),
			MIX_LOG_PTR( ppTexture ) );

		return False;
	}

	HRESULT ret;
	D3D11_TEXTURE2D_DESC texDesc;
	D3D11_DEPTH_STENCIL_VIEW_DESC dsViewDesc;
	ID3D11Texture2D* pD3DTexture;
	ID3D11DepthStencilView* pD3DDSView;
	Mix::Graphics::DX11::TextureDepth* pTexture;

	if( IsDepthTextureSupported( format ) == False )
	{
		MIX_LOG_ERROR( L"%s : サポートされないフォーマット : %s[%s] %s[%s]", FAILED_CREATE_TEXTURE_DEPTH,
			Mix::STR_DEBUGNAME, MIX_SAFE_NAME( pDebugName ), Mix::STR_FORMAT, GetFormatText( format ) );

		return False;
	}

	texDesc.Width = width;
	texDesc.Height = height;
	texDesc.MipLevels = 1;
	texDesc.ArraySize = 1;
	texDesc.Format = m_ResourceFmtList[format].format;
	texDesc.SampleDesc.Count = 1;
	texDesc.SampleDesc.Quality = 0;
	texDesc.Usage = D3D11_USAGE_DEFAULT;
	texDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
	texDesc.CPUAccessFlags = 0;
	texDesc.MiscFlags = 0;

	ret = m_pD3DDevice->CreateTexture2D( &texDesc, NULL, &pD3DTexture );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : CreateTexture2D %s : %s[%s] %s[%s]", FAILED_CREATE_TEXTURE_DEPTH,
			Mix::STR_RETERROR, Mix::STR_DEBUGNAME, MIX_SAFE_NAME( pDebugName ), Mix::STR_RESULT, GetD3DResultText( ret ) );

		return False;
	}

	dsViewDesc.Format = m_ResourceFmtList[format].format;
	dsViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
	dsViewDesc.Flags = 0;
	dsViewDesc.Texture2D.MipSlice = 0;

	ret = m_pD3DDevice->CreateDepthStencilView( pD3DTexture, &dsViewDesc, &pD3DDSView );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : CreateDepthStencilView %s : %s[%s] %s[%s]", FAILED_CREATE_TEXTURE_DEPTH,
			Mix::STR_RETERROR, Mix::STR_DEBUGNAME, MIX_SAFE_NAME( pDebugName ), Mix::STR_RESULT, GetD3DResultText( ret ) );

		MIX_RELEASE( pD3DTexture );

		return False;
	}

	pTexture = Mix::Graphics::DX11::TextureDepth::CreateInstance(	this,
																	width, height, format,
																	pD3DTexture, pD3DDSView );
	if( pTexture != NULL )
	{
		( *ppTexture ) = pTexture;
	}
	else
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s]", FAILED_CREATE_TEXTURE_DEPTH,
			Mix::STR_OUTOFMEMORY, Mix::STR_DEBUGNAME, MIX_SAFE_NAME( pDebugName ) );

		MIX_RELEASE( pD3DDSView );
		MIX_RELEASE( pD3DTexture );

		return False;
	}
	return True;
}

Boolean Device::CreateQuery( Mix::Graphics::QUERY_FORMAT format, Mix::Graphics::IQuery** ppQuery, const wchar_t* pDebugName )
{
	if( ppQuery == NULL )
	{
		MIX_LOG_ERROR( L"%s : %s : DebugName[%s] ppQuery[%s]", FAILED_CREATE_QUERY,
			Mix::STR_ILLEGALARG,
			Mix::STR_DEBUGNAME,
			MIX_SAFE_NAME( pDebugName ),
			MIX_LOG_PTR( ppQuery ) );

		return False;
	}

	HRESULT ret;
	ID3D11Query* pD3DQuery;
	Mix::Graphics::DX11::Query* pQuery;

	ret = m_pD3DDevice->CreateQuery( &( Device::D3DQueryDescTable[format] ), &pD3DQuery );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : ID3D11Device::CreateQuery %s : %s[%s] %s[%s] %s[%s]", FAILED_CREATE_QUERY,
			Mix::STR_RETERROR, Mix::STR_DEBUGNAME, MIX_SAFE_NAME( pDebugName ), Mix::STR_FORMAT, Device::D3DQueryTextTable[format], Mix::STR_RESULT, GetD3DResultText( ret ) );

		return False;
	}

	pQuery = Mix::Graphics::DX11::Query::CreateInstance( this, format, pD3DQuery );
	if( pQuery == NULL )
	{
		MIX_LOG_ERROR( L"%s : %s : %s[%s]", FAILED_CREATE_QUERY, Mix::STR_OUTOFMEMORY, Mix::STR_FORMAT, Device::D3DQueryTextTable[format] );
		MIX_RELEASE( pD3DQuery );
		return False;
	}

	( *ppQuery ) = pQuery;

	return True;
}

Mix::Graphics::IDevice::DISPLAY_MODE Device::GetDisplayMode( void ) const
{
	return m_DispMode;
}

void Device::SetDisplayMode( Mix::Graphics::IDevice::DISPLAY_MODE dispMode )
{
	if( ( m_pEngine->IsSizeableWindow() == True ) || ( m_DispMode == dispMode ) )
	{
		return;
	}

	if( m_pDXGISwapChain->SetFullscreenState( ( dispMode == Mix::Graphics::IDevice::FULLSCREEN )? TRUE : FALSE, NULL ) == S_OK )
	{
		ResizeBackBuffer();
		m_DispMode = dispMode;
	}
}

void Device::ToggleDisplayMode( void )
{
	SetDisplayMode( ( m_DispMode == Mix::Graphics::IDevice::WINDOW )? Mix::Graphics::IDevice::FULLSCREEN : Mix::Graphics::IDevice::WINDOW );
}

Boolean Device::Begin( void )
{
	m_DrawPrimitiveCount = 0;

	return True;
}

void Device::End( void )
{
	ResetTargetState();
	ResetDrawState();
}

void Device::Present( void )
{
	if( m_pEngine->IsSizeableWindow() == True )
	{
//		D3D11_MAPPED_SUBRESOURCE vbMapped;

		D3D11_TEXTURE2D_DESC bbDesc;
		m_pBackBuffer->GetDesc( &bbDesc );

		D3D11_VIEWPORT viewport = {
			0.0f, 0.0f,
			static_cast<Float32>( bbDesc.Width ), static_cast<Float32>( bbDesc.Height ),
			m_Viewport.MinDepth, m_Viewport.MaxDepth
		};

		D3D11_RECT scissorRect = {
			0, 0,
			bbDesc.Width, bbDesc.Height
		};

		ID3D11RenderTargetView* rtvTable[Mix::Graphics::TARGET_MAX] = { NULL };
		rtvTable[0] = m_pBackBufferView;

		ID3D11SamplerState* samplerTable[1] = { m_pSamplerArray[Mix::Graphics::TEXTURE_FILTER_POINT][Mix::Graphics::TEXTURE_ADDRESS_CLAMP] };

		ID3D11ShaderResourceView* srvTable[10] = { NULL };
		srvTable[0] = m_pPresentSRV;

		ID3D11Buffer* vbTable[1] = { m_pPresentVB };
		UInt32 vbStrideTable[1] = { 24 };
		UInt32 vbOffsetTable[1] = { 0 };
/*
		if( m_pD3DDeviceContext->Map( m_pPresentVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &vbMapped ) == S_OK )
		{
			PRESENT_VERTEX* pv = static_cast<Device::PRESENT_VERTEX*>( vbMapped.pData );

			Float32 sw = MIX_FLOAT_RECIPROCAL( static_cast<Float32>( m_ScreenSize.x ) );
			Float32 sh = MIX_FLOAT_RECIPROCAL( static_cast<Float32>( m_ScreenSize.y ) );
			Float32 sx = static_cast<Float32>( ( m_ScreenSize.x - bbDesc.Width ) >> 1 ) * sw;
			Float32 sy = static_cast<Float32>( ( m_ScreenSize.y - bbDesc.Height ) >> 1 ) * sh;
			Float32 sxx = sx + static_cast<Float32>( bbDesc.Width ) * sw;
			Float32 syy = sy + static_cast<Float32>( bbDesc.Height ) * sh;

			pv[0].pos.Set( -1.0f, +1.0f, 0.0f, 1.0f );
			pv[0].tex.Set( sx, sy );

			pv[1].pos.Set( +1.0f, +1.0f, 0.0f, 1.0f );
			pv[1].tex.Set( sxx, sy );

			pv[2].pos.Set( -1.0f, -1.0f, 0.0f, 1.0f );
			pv[2].tex.Set( sx, syy );

			pv[3].pos.Set( +1.0f, -1.0f, 0.0f, 1.0f );
			pv[3].tex.Set( sxx, syy );

			m_pD3DDeviceContext->Unmap( m_pPresentVB, 0 );
		}
*/
		m_pD3DDeviceContext->RSSetViewports( 1, &viewport );
		m_pD3DDeviceContext->RSSetScissorRects( 1, &scissorRect );
		m_pD3DDeviceContext->RSSetState( m_pRasterizerStateArray[Mix::Graphics::FILL_SOLID][Mix::Graphics::CULL_NONE][0] );

		m_pD3DDeviceContext->OMSetRenderTargets( Mix::Graphics::TARGET_MAX, rtvTable, NULL );
		m_pD3DDeviceContext->OMSetDepthStencilState( m_pDepthStateArray[0][0][ Mix::Graphics::ZFUNC_LESSEQUAL], 0 );
		m_pD3DDeviceContext->OMSetBlendState( m_pBlendStateArray[Mix::Graphics::BLEND_COPY][Mix::Graphics::COLOR_WRITE_RGBA], NULL, 0xFFFFFFFF );

		m_pD3DDeviceContext->HSSetShader( NULL, NULL, 0 );
		m_pD3DDeviceContext->DSSetShader( NULL, NULL, 0 );
		m_pD3DDeviceContext->GSSetShader( NULL, NULL, 0 );

		m_pD3DDeviceContext->VSSetShader( m_pPresentVS, NULL, 0 );

		m_pD3DDeviceContext->PSSetShader( m_pPresentPS, NULL, 0 );
		m_pD3DDeviceContext->PSSetSamplers( 0, 1, samplerTable );
		m_pD3DDeviceContext->PSSetShaderResources( 0, 1, srvTable );

		m_pD3DDeviceContext->IASetInputLayout( m_pPresentVL );
		m_pD3DDeviceContext->IASetVertexBuffers( 0,	1, vbTable, vbStrideTable, vbOffsetTable );
		m_pD3DDeviceContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP );

		m_pD3DDeviceContext->Draw( 4, 0 );
	}

	m_pDXGISwapChain->Present( ( m_bWaitVSync == True )? 1 : 0, 0 );
}

void Device::SetTarget( Mix::Graphics::ITexture* pT0, Mix::Graphics::ITexture* pT1, Mix::Graphics::ITexture* pT2, Mix::Graphics::ITexture* pT3, Mix::Graphics::ITexture* pDS )
{
	if( ( ( pT0 != NULL ) && ( pT0->GetBindType() != Mix::Graphics::ITexture::BIND_TARGET ) ) ||
		( ( pT1 != NULL ) && ( pT1->GetBindType() != Mix::Graphics::ITexture::BIND_TARGET ) ) ||
		( ( pT2 != NULL ) && ( pT2->GetBindType() != Mix::Graphics::ITexture::BIND_TARGET ) ) ||
		( ( pT3 != NULL ) && ( pT3->GetBindType() != Mix::Graphics::ITexture::BIND_TARGET ) ) ||
		( ( pDS != NULL ) && ( pDS->GetBindType() != Mix::Graphics::ITexture::BIND_DEPTH ) ) )
	{
		MIX_LOG_ERROR( L"ターゲットの設定に失敗 : %s : pT0[%s] pT1[%s] pT2[%s] pT3[%s] pDS[%s]",
			Mix::STR_ILLEGALARG,
			( ( pT0 == NULL ) || ( pT0->GetType() == Mix::Graphics::ITexture::BIND_TARGET ) )? L"○" : L"×",
			( ( pT1 == NULL ) || ( pT1->GetType() == Mix::Graphics::ITexture::BIND_TARGET ) )? L"○" : L"×",
			( ( pT2 == NULL ) || ( pT2->GetType() == Mix::Graphics::ITexture::BIND_TARGET ) )? L"○" : L"×",
			( ( pT3 == NULL ) || ( pT3->GetType() == Mix::Graphics::ITexture::BIND_TARGET ) )? L"○" : L"×",
			( ( pDS == NULL ) || ( pDS->GetType() == Mix::Graphics::ITexture::BIND_DEPTH ) )? L"○" : L"×" );

		return;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// ID3D11DeviceContext にターゲットを設定
	////////////////////////////////////////////////////////////////////////////////////////////////////

	ID3D11ShaderResourceView* pSRViewArray[10] = { NULL };	//テクスチャステージ最大数をクリア( ターゲットより、テクスチャのほうが設定できるリソースが多いから )
	ID3D11RenderTargetView* pRTViewArray[Mix::Graphics::TARGET_MAX];
	ID3D11DepthStencilView* pDSView;

	if( pT0 != NULL )
	{
		pRTViewArray[0] = static_cast<Mix::Graphics::DX11::TextureTarget*>( pT0 )->GetRTView();
	}
	else
	{
		pRTViewArray[0] = ( m_pEngine->IsSizeableWindow() == False )? m_pBackBufferView : m_pPresentRTV;
	}

	pRTViewArray[1] = ( pT1 != NULL )? static_cast<Mix::Graphics::DX11::TextureTarget*>( pT1 )->GetRTView() : NULL;
	pRTViewArray[2] = ( pT2 != NULL )? static_cast<Mix::Graphics::DX11::TextureTarget*>( pT2 )->GetRTView() : NULL;
	pRTViewArray[3] = ( pT3 != NULL )? static_cast<Mix::Graphics::DX11::TextureTarget*>( pT3 )->GetRTView() : NULL;

	pDSView = ( pDS != NULL )? static_cast<Mix::Graphics::DX11::TextureDepth*>( pDS )->GetDSView() : NULL;

	m_pD3DDeviceContext->PSSetShaderResources( 0, 10, pSRViewArray );
	m_pD3DDeviceContext->OMSetRenderTargets( Mix::Graphics::TARGET_MAX, pRTViewArray, pDSView );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// テクスチャの破棄( シェーダーリソースを NULL に設定したため )
	////////////////////////////////////////////////////////////////////////////////////////////////////

	//テクスチャ
	for( UInt32 i = 0; i < Mix::Graphics::TEXTURESTAGE_MAX; i++ )
	{
		m_DrawState.textureTable[i] = NULL;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// ターゲットを保存
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( pT0 != NULL )
	{
		m_TargetState.rect = Mix::Rectangle( 0, 0, pT0->GetWidth(), pT0->GetHeight() );
	}
	else
	{
		m_TargetState.rect = Mix::Rectangle( 0, 0, m_ScreenSize.x, m_ScreenSize.y );
	}

	MIX_RELEASE( m_TargetState.pT0 );
	MIX_ADD_REF( pT0 );
	m_TargetState.pT0 = pT0;

	MIX_RELEASE( m_TargetState.pT1 );
	MIX_ADD_REF( pT1 );
	m_TargetState.pT1 = pT1;

	MIX_RELEASE( m_TargetState.pT2 );
	MIX_ADD_REF( pT2 );
	m_TargetState.pT2 = pT2;

	MIX_RELEASE( m_TargetState.pT3 );
	MIX_ADD_REF( pT3 );
	m_TargetState.pT3 = pT3;

	MIX_RELEASE( m_TargetState.pDS );
	MIX_ADD_REF( pDS );
	m_TargetState.pDS = pDS;
}

void Device::GetTarget( Mix::Graphics::ITexture** ppT0, Mix::Graphics::ITexture** ppT1, Mix::Graphics::ITexture** ppT2, Mix::Graphics::ITexture** ppT3, Mix::Graphics::ITexture** ppDS )
{
	if( ppT0 != NULL )
	{
		MIX_ADD_REF( m_TargetState.pT0 );
		( *ppT0 ) = m_TargetState.pT0;
	}

	if( ppT1 != NULL )
	{
		MIX_ADD_REF( m_TargetState.pT1 );
		( *ppT1 ) = m_TargetState.pT1;
	}

	if( ppT2 != NULL )
	{
		MIX_ADD_REF( m_TargetState.pT2 );
		( *ppT2 ) = m_TargetState.pT2;
	}

	if( ppT3 != NULL )
	{
		MIX_ADD_REF( m_TargetState.pT3 );
		( *ppT3 ) = m_TargetState.pT3;
	}

	if( ppDS != NULL )
	{
		MIX_ADD_REF( m_TargetState.pDS );
		( *ppDS ) = m_TargetState.pDS;
	}
}

const Mix::Rectangle& Device::GetViewBounds( void ) const
{
	return m_ViewportRect;
}

void Device::SetViewBounds( const Mix::Rectangle& rect )
{
	SetViewBounds( rect.x, rect.y, rect.width, rect.height );
}

void Device::SetViewBounds( Int32 x, Int32 y, Int32 width, Int32 height )
{
	if( m_TargetState.rect.Contains( Mix::Rectangle( x, y, width, height ), &m_ViewportRect ) == False )
	{
		m_ViewportRect.x = 0;
		m_ViewportRect.y = 0;
		m_ViewportRect.width = 1;
		m_ViewportRect.height = 1;
	}

	m_Viewport.TopLeftX = static_cast<Float32>( m_ViewportRect.x );
	m_Viewport.TopLeftY = static_cast<Float32>( m_ViewportRect.y );
	m_Viewport.Width = static_cast<Float32>( m_ViewportRect.width );
	m_Viewport.Height = static_cast<Float32>( m_ViewportRect.height );

	m_pD3DDeviceContext->RSSetViewports( 1, &m_Viewport );
}

const Mix::Rectangle& Device::GetScissorBounds( void ) const
{
	return m_ScissorRect;
}

void Device::SetScissorBounds( const Mix::Rectangle& rect )
{
	SetScissorBounds( rect.x, rect.y, rect.width, rect.height );
}

void Device::SetScissorBounds( Int32 x, Int32 y, Int32 width, Int32 height )
{
	D3D11_RECT rect;

	if( m_TargetState.rect.Contains( Mix::Rectangle( x, y, width, height ), &m_ScissorRect ) == False )
	{
		m_ScissorRect.x = 0;
		m_ScissorRect.y = 0;
		m_ScissorRect.width = 1;
		m_ScissorRect.height = 1;
	}

	rect.left = m_ScissorRect.x;
	rect.top = m_ScissorRect.y;
	rect.right = m_ScissorRect.x + m_ScissorRect.width;
	rect.bottom = m_ScissorRect.y + m_ScissorRect.height;

	m_pD3DDeviceContext->RSSetScissorRects( 1, &rect );
}

void Device::Clear( Boolean clearTarget, Boolean clearDepth, const Mix::Vector4& color, Float32 z )
{
	UInt32 i;
	ID3D11RenderTargetView* rtvTable[Mix::Graphics::TARGET_MAX] = { NULL };
	ID3D11DepthStencilView* pDSView = NULL;

	//ターゲットとデプス/ステンシルを取得
	m_pD3DDeviceContext->OMGetRenderTargets( Mix::Graphics::TARGET_MAX, rtvTable, &pDSView );

	//ターゲットをクリア
	if( clearTarget == True )
	{
		for( i = 0; i < Mix::Graphics::TARGET_MAX; i++ )
		{
			if( rtvTable[i] != NULL )
			{
				m_pD3DDeviceContext->ClearRenderTargetView( rtvTable[i], color.data );
			}
		}
	}

	//デプス/ステンシルをクリア
	if( ( clearDepth == True ) &&
		( pDSView != NULL ) )
	{
		m_pD3DDeviceContext->ClearDepthStencilView( pDSView, D3D11_CLEAR_DEPTH, z, 0 );
	}

	//ターゲットを解放
	for( i = 0; i < Mix::Graphics::TARGET_MAX; i++ )
	{
		MIX_RELEASE( rtvTable[i] );
	}

	//デプス・ステンシルを解放
	MIX_RELEASE( pDSView );
}

void Device::SetRasterizerState( Mix::Graphics::FILL_TYPE fillMode, Mix::Graphics::CULL_TYPE cullMode, Boolean bScissoring )
{
	Mix::Graphics::RASTERIZER_DESC desc;

	desc.fillMode = fillMode;
	desc.cullMode = cullMode;
	desc.bScissoring = bScissoring;

	SetRasterizerState( desc );
}

void Device::SetRasterizerState( const Mix::Graphics::RASTERIZER_DESC& desc )
{
	UInt32 fillIdx = desc.fillMode;
	UInt32 cullIdx = desc.cullMode;
	UInt32 scissorIdx = ( desc.bScissoring == True )? 1 : 0;

	m_RasterizeDesc = desc;
	m_pD3DDeviceContext->RSSetState( m_pRasterizerStateArray[fillIdx][cullIdx][scissorIdx] );
}

const Mix::Graphics::RASTERIZER_DESC& Device::GetRasterizerState( void ) const
{
	return m_RasterizeDesc;
}

void Device::SetDepthState( Boolean bTest, Boolean bWrite, Mix::Graphics::ZFUNC_TYPE func )
{
	Mix::Graphics::DEPTH_DESC desc;

	desc.bTest = bTest;
	desc.bWrite = bWrite;
	desc.func = func;

	SetDepthState( desc );
}

void Device::SetDepthState( const Mix::Graphics::DEPTH_DESC& desc )
{
	UInt32 testIdx = ( desc.bTest == True )? 1 : 0;
	UInt32 writeIdx = ( desc.bWrite == True )? 1 : 0;
	UInt32 funcIdx = desc.func;

	m_DepthDesc = desc;
	m_pD3DDeviceContext->OMSetDepthStencilState( m_pDepthStateArray[testIdx][writeIdx][funcIdx], 0 );
}

const Mix::Graphics::DEPTH_DESC& Device::GetDepthState( void ) const
{
	return m_DepthDesc;
}

void Device::SetBlendState( Mix::Graphics::BLEND_TYPE type, Mix::Graphics::COLOR_WRITE_MASK colorWriteMask )
{
	Mix::Graphics::BLEND_DESC desc;

	desc.type = type;
	desc.colorWriteMask = colorWriteMask;

	SetBlendState( desc );
}

void Device::SetBlendState( const Mix::Graphics::BLEND_DESC& desc )
{
	m_BlendDesc = desc;
	m_pD3DDeviceContext->OMSetBlendState( m_pBlendStateArray[m_BlendDesc.type][m_BlendDesc.colorWriteMask], NULL, 0xFFFFFFFF );
}

const Mix::Graphics::BLEND_DESC& Device::GetBlendState( void ) const
{
	return m_BlendDesc;
}

void Device::SetVertexLayout( Mix::Graphics::IVertexLayout* pVertexLayout )
{
	m_DrawState.next.pVertexLayout = pVertexLayout;
}

void Device::SetHullShader( Mix::Graphics::IHullShader* pHullShader )
{
	if( MIX_TESTBIT( m_Caps.flags, Device::HAL_DOMAIN_SHADER ) != Device::HAL_DOMAIN_SHADER )
	{
		MIX_LOG_ERROR( L"ハルシェーダーの設定に失敗 : シェーダーモデル 5 の場合のみ使用できます" );
		return;
	}

	m_DrawState.next.pHullShader = pHullShader;
}

void Device::SetDomainShader( Mix::Graphics::IDomainShader* pDomainShader )
{
	if( MIX_TESTBIT( m_Caps.flags, Device::HAL_DOMAIN_SHADER ) != Device::HAL_DOMAIN_SHADER )
	{
		MIX_LOG_ERROR( L"ドメインシェーダーの設定に失敗 : シェーダーモデル 5 の場合のみ使用できます" );
		return;
	}

	m_DrawState.next.pDomainShader = pDomainShader;
}

void Device::SetGeometryShader( Mix::Graphics::IGeometryShader* pGeometryShader )
{
	m_DrawState.next.pGeometryShader = pGeometryShader;
}

void Device::SetVertexShader( Mix::Graphics::IVertexShader* pVertexShader )
{
	m_DrawState.next.pVertexShader = pVertexShader;
}

void Device::SetPixelShader( Mix::Graphics::IPixelShader* pPixelShader )
{
	m_DrawState.next.pPixelShader = pPixelShader;
}

void Device::SetVertexShaderConstantB( UInt32 startRegister, const Boolean* data, UInt32 count )
{
	MIX_ERROR( L"バーテックスシェーダーコンスタントの設定に失敗 : シェーダーモデル 4、もしくわ 5 で SetVertexShaderConstantB は使用できません" );
}

void Device::SetVertexShaderConstantI( UInt32 startRegister, const Int32* data, UInt32 count )
{
	MIX_ERROR( L"バーテックスシェーダーコンスタントの設定に失敗 : シェーダーモデル 4、もしくわ 5 で SetVertexShaderConstantI は使用できません" );
}

void Device::SetVertexShaderConstantF( UInt32 startRegister, const Float32* data, UInt32 count )
{
	MIX_ERROR( L"バーテックスシェーダーコンスタントの設定に失敗 : シェーダーモデル 4、もしくわ 5 で SetVertexShaderConstantF は使用できません" );
}

void Device::SetVertexShaderConstantF( UInt32 startRegister, const Mix::Vector4* data, UInt32 count )
{
	MIX_ERROR( L"バーテックスシェーダーコンスタントの設定に失敗 : シェーダーモデル 4、もしくわ 5 で SetVertexShaderConstantF は使用できません" );
}

void Device::SetVertexShaderConstantF( UInt32 startRegister, const Mix::Matrix4x4* data, UInt32 count )
{
	MIX_ERROR( L"バーテックスシェーダーコンスタントの設定に失敗 : シェーダーモデル 4、もしくわ 5 で SetVertexShaderConstantF は使用できません" );
}

void Device::SetPixelShaderConstantB( UInt32 startRegister, const Boolean* data, UInt32 count )
{
	MIX_ERROR( L"ピクセルシェーダーコンスタントの設定に失敗 : シェーダーモデル 4 、もしくわ 5 で SetPixelShaderConstantB は使用できません" );
}

void Device::SetPixelShaderConstantI( UInt32 startRegister, const Int32* data, UInt32 count )
{
	MIX_ERROR( L"ピクセルシェーダーコンスタントの設定に失敗 : シェーダーモデル 4、もしくわ 5 で SetPixelShaderConstantI は使用できません" );
}

void Device::SetPixelShaderConstantF( UInt32 startRegister, const Float32* data, UInt32 count )
{
	MIX_ERROR( L"ピクセルシェーダーコンスタントの設定に失敗 : シェーダーモデル 4、もしくわ 5 で SetPixelShaderConstantF は使用できません" );
}

void Device::SetPixelShaderConstantF( UInt32 startRegister, const Mix::Vector4* data, UInt32 count )
{
	MIX_ERROR( L"ピクセルシェーダーコンスタントの設定に失敗 : シェーダーモデル 4、もしくわ 5 で SetPixelShaderConstantF は使用できません" );
}

void Device::SetPixelShaderConstantF( UInt32 startRegister, const Mix::Matrix4x4* data, UInt32 count )
{
	MIX_ERROR( L"ピクセルシェーダーコンスタントの設定に失敗 : シェーダーモデル 4、もしくわ 5 で SetPixelShaderConstantF は使用できません" );
}

void Device::SetHullShaderConstant( UInt32 slot, Mix::Graphics::IShaderConstant* pShaderConstant )
{
	if( MIX_TESTBIT( m_Caps.flags, Device::HAL_DOMAIN_SHADER ) != Device::HAL_DOMAIN_SHADER )
	{
		MIX_LOG_ERROR( L"ハルシェーダーコンスタントの設定に失敗 : シェーダーモデル 5 の場合のみ使用できます" );
		return;
	}

	if( ( slot >= D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT ) ||
		( pShaderConstant == NULL ) )
	{
		MIX_LOG_ERROR( L"ハルシェーダーコンスタントの設定に失敗 : %s : slot[%d]( 0〜13 ) pShaderConstant[%s]",
			Mix::STR_ILLEGALARG,
			slot,
			MIX_LOG_PTR( pShaderConstant ) );

		return;
	}

	if( m_DrawState.hscTable[slot] != pShaderConstant )
	{
		ID3D11Buffer* buffTable[1] = { static_cast<Mix::Graphics::DX11::ShaderConstant*>( pShaderConstant )->GetInterface() };

		m_pD3DDeviceContext->HSSetConstantBuffers( slot, 1, buffTable );
		m_DrawState.hscTable[slot] = pShaderConstant;
	}
}

void Device::SetDomainShaderConstant( UInt32 slot, Mix::Graphics::IShaderConstant* pShaderConstant )
{
	if( MIX_TESTBIT( m_Caps.flags, Device::HAL_DOMAIN_SHADER ) != Device::HAL_DOMAIN_SHADER )
	{
		MIX_LOG_ERROR( L"ドメインシェーダーコンスタントの設定に失敗 : シェーダーモデル 5 の場合のみ使用できます" );
		return;
	}

	if( ( slot >= D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT ) ||
		( pShaderConstant == NULL ) )
	{
		MIX_LOG_ERROR( L"ドメインシェーダーコンスタントの設定に失敗 : %s : slot[%d]( 0〜13 ) pShaderConstant[%s]",
			Mix::STR_ILLEGALARG,
			slot,
			MIX_LOG_PTR( pShaderConstant ) );

		return;
	}

	if( m_DrawState.dscTable[slot] != pShaderConstant )
	{
		ID3D11Buffer* buffTable[1] = { static_cast<Mix::Graphics::DX11::ShaderConstant*>( pShaderConstant )->GetInterface() };

		m_pD3DDeviceContext->DSSetConstantBuffers( slot, 1, buffTable );
		m_DrawState.dscTable[slot] = pShaderConstant;
	}
}

void Device::SetGeometryShaderConstant( UInt32 slot, Mix::Graphics::IShaderConstant* pShaderConstant )
{
	if( ( slot >= D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT ) ||
		( pShaderConstant == NULL ) )
	{
		MIX_LOG_ERROR( L"ジオメトリシェーダーコンスタントの設定に失敗 : %s : slot[%d]( 0〜13 ) pShaderConstant[%s]",
			Mix::STR_ILLEGALARG,
			slot,
			MIX_LOG_PTR( pShaderConstant ) );

		return;
	}

	if( m_DrawState.gscTable[slot] != pShaderConstant )
	{
		ID3D11Buffer* buffTable[1] = { static_cast<Mix::Graphics::DX11::ShaderConstant*>( pShaderConstant )->GetInterface() };

		m_pD3DDeviceContext->GSSetConstantBuffers( slot, 1, buffTable );
		m_DrawState.gscTable[slot] = pShaderConstant;
	}
}

void Device::SetVertexShaderConstant( UInt32 slot, Mix::Graphics::IShaderConstant* pShaderConstant )
{
	if( ( slot >= D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT ) ||
		( pShaderConstant == NULL ) )
	{
		MIX_LOG_ERROR( L"バーテックスシェーダーコンスタントの設定に失敗 : %s : slot[%d]( 0〜13 ) pShaderConstant[%s]",
			Mix::STR_ILLEGALARG,
			slot,
			MIX_LOG_PTR( pShaderConstant ) );

		return;
	}

	if( m_DrawState.vscTable[slot] != pShaderConstant )
	{
		ID3D11Buffer* buffTable[1] = { static_cast<Mix::Graphics::DX11::ShaderConstant*>( pShaderConstant )->GetInterface() };

		m_pD3DDeviceContext->VSSetConstantBuffers( slot, 1, buffTable );
		m_DrawState.vscTable[slot] = pShaderConstant;
	}
}

void Device::SetPixelShaderConstant( UInt32 slot, Mix::Graphics::IShaderConstant* pShaderConstant )
{
	if( ( slot >= D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT ) ||
		( pShaderConstant == NULL ) )
	{
		MIX_LOG_ERROR( L"ピクセルシェーダーコンスタントの設定に失敗 : %s : slot[%d]( 0〜13 ) pShaderConstant[%s]",
			Mix::STR_ILLEGALARG,
			slot,
			MIX_LOG_PTR( pShaderConstant ) );

		return;
	}

	if( m_DrawState.pscTable[slot] != pShaderConstant )
	{
		ID3D11Buffer* bufferTable[1] = { static_cast<Mix::Graphics::DX11::ShaderConstant*>( pShaderConstant )->GetInterface() };

		m_pD3DDeviceContext->PSSetConstantBuffers( slot, 1, bufferTable );
		m_DrawState.pscTable[slot] = pShaderConstant;
	}
}

void Device::SetVertexBuffer( Mix::Graphics::IVertexBuffer* pVertexBuffer )
{
	m_DrawState.next.pVertexBuffer = pVertexBuffer;
}

void Device::SetIndexBuffer( Mix::Graphics::IIndexBuffer* pIndexBuffer )
{
	m_DrawState.next.pIndexBuffer = pIndexBuffer;
}

UInt32 Device::GetTextureStageMax( void ) const
{
	return Mix::Graphics::TEXTURESTAGE_MAX;
}

void Device::SetTexture( UInt32 stage, Mix::Graphics::TEXTURE_FILTER_TYPE filter, Mix::Graphics::TEXTURE_ADDRESS_TYPE address, Mix::Graphics::ITexture* pTexture )
{
	if( ( GetTextureStageMax() <= stage ) ||
		( ( pTexture != NULL ) && ( ( pTexture->GetAccessFlags() & ITexture::ACCESS_GPU_READ ) != ITexture::ACCESS_GPU_READ ) ) )
	{
		UInt32 stageLast = GetTextureStageMax() - 1;

		MIX_LOG_ERROR( L"テクスチャの設定に失敗 : %s : stage[%d/%d] pTexture[%s]",
			Mix::STR_ILLEGALARG,
			stage, stageLast,
			( ( pTexture == NULL ) || ( ( pTexture->GetAccessFlags() & ITexture::ACCESS_GPU_READ ) == ITexture::ACCESS_GPU_READ ) )? L"○" : L"×" );

		return;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// サンプラーステートの設定
	////////////////////////////////////////////////////////////////////////////////////////////////////

	::ID3D11SamplerState* ssTable[1] = { m_pSamplerArray[filter][address] };

	if( m_DrawState.samplerTable[stage] != ssTable[0] )
	{
		m_pD3DDeviceContext->PSSetSamplers( stage, 1, ssTable );
		m_DrawState.samplerTable[stage] = ssTable[0];
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// テクスチャの設定
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( m_DrawState.textureTable[stage] != pTexture )
	{
		::ID3D11ShaderResourceView* srvTable[1] = {
			( pTexture != NULL )? static_cast<Mix::Graphics::DX11::Texture*>( pTexture )->GetSRView() : NULL };

		m_pD3DDeviceContext->PSSetShaderResources( stage, 1, srvTable );
		m_DrawState.textureTable[stage] = pTexture;
	}
}

void Device::ResetTexture( UInt32 stage )
{
	if( stage >= Mix::Graphics::TEXTURESTAGE_MAX )
	{
		MIX_LOG_ERROR( L"テクスチャのリセットに失敗 : %s : stage[0 <= %d <= 7]", Mix::STR_ILLEGALARG, stage );
		return;
	}

	if( m_DrawState.textureTable[stage] != NULL )
	{
		::ID3D11ShaderResourceView* srvTable[1] = { NULL };

		m_pD3DDeviceContext->PSSetShaderResources( stage, 1, srvTable );
		m_DrawState.textureTable[stage] = NULL;
	}
}

void Device::Draw( Mix::Graphics::PRIMITIVE_TYPE primitiveType, UInt32 startVertex, UInt32 numVertex )
{
	if( numVertex == 0 )
	{
		MIX_LOG_ERROR( L"%s : %s : numVertex[%d > 0]", FAILED_DRAW, Mix::STR_ILLEGALARG, numVertex );
		return;
	}

	if( ( m_DrawState.next.pVertexLayout == NULL ) ||
		( m_DrawState.next.pVertexShader == NULL ) ||
		( m_DrawState.next.pPixelShader == NULL ) ||
		( m_DrawState.next.pVertexBuffer == NULL ) )
	{
		MIX_LOG_ERROR( L"%s : %s : VertexLayout[%s] VertexShader[%s] PixelShader[%s] VertexBuffer[%s]",
			FAILED_DRAW,
			MSG_NOT_SET_DEVOBJ,
			MIX_LOG_PTR( m_DrawState.next.pVertexLayout ),
			MIX_LOG_PTR( m_DrawState.next.pVertexShader ),
			MIX_LOG_PTR( m_DrawState.next.pPixelShader ),
			MIX_LOG_PTR( m_DrawState.next.pVertexBuffer ) );

		return;
	}

	FlushDrawState( 0, 0 );

	m_pD3DDeviceContext->IASetPrimitiveTopology( Device::D3DPrimitiveTopologyTable[primitiveType] );
	m_pD3DDeviceContext->Draw( numVertex, startVertex );

	m_DrawPrimitiveCount += ComputePrimitiveCount( primitiveType, numVertex );
}

void Device::DrawIndexed( Mix::Graphics::PRIMITIVE_TYPE primitiveType, UInt32 startVertex, UInt32 numVertex, UInt32 startIndex, UInt32 numIndex )
{
	if( ( numVertex == 0 ) ||
		( numIndex == 0 ) )
	{
		MIX_LOG_ERROR( L"%s : %s : numVertex[%d > 0] numIndex[%d > 0]", FAILED_DRAW_INDEXED, Mix::STR_ILLEGALARG, numVertex, numIndex );
		return;
	}

	if( ( m_DrawState.next.pVertexLayout == NULL ) ||
		( m_DrawState.next.pVertexShader == NULL ) ||
		( m_DrawState.next.pPixelShader == NULL ) ||
		( m_DrawState.next.pVertexBuffer == NULL ) ||
		( m_DrawState.next.pIndexBuffer == NULL ) )
	{
		MIX_LOG_ERROR( L"%s : %s : VertexLayout[%s] VertexShader[%s] PixelShader[%s] VertexBuffer[%s] IndexBuffer[%s]",
			FAILED_DRAW_INDEXED,
			MSG_NOT_SET_DEVOBJ,
			MIX_LOG_PTR( m_DrawState.next.pVertexLayout ),
			MIX_LOG_PTR( m_DrawState.next.pVertexShader ),
			MIX_LOG_PTR( m_DrawState.next.pPixelShader ),
			MIX_LOG_PTR( m_DrawState.next.pVertexBuffer ),
			MIX_LOG_PTR( m_DrawState.next.pIndexBuffer ) );

		return;
	}

	FlushDrawState( 0, 0 );

	m_pD3DDeviceContext->IASetPrimitiveTopology( Device::D3DPrimitiveTopologyTable[primitiveType] );
	m_pD3DDeviceContext->DrawIndexed( numIndex, startIndex, 0 );

	m_DrawPrimitiveCount += ComputePrimitiveCount( primitiveType, numIndex );
}

Boolean Device::SaveScreenshot( const wchar_t* pFilePath )
{
	if( ( pFilePath == NULL ) ||
		( wcslen( pFilePath ) == 0 ) ||
		( m_pBackBuffer == NULL ) )
	{
		return False;
	}

	wchar_t fileExt[5];

	D3D11_TEXTURE2D_DESC bbDesc;
	D3D11_TEXTURE2D_DESC ssDesc;
	ID3D11Texture2D* pTex;

	UInt32 imgByteSize;
	UInt32* pImage;

	D3D11_MAPPED_SUBRESOURCE mappedSubRes;

	BITMAPFILEHEADER bmpFileHeader;
	BITMAPCOREHEADER bmpCoreHeader;

	HANDLE hFile;
	DWORD writeSize;

	////////////////////////////////////////////////////////////////////////////////////////////////////

	::wcscpy_s( fileExt, 5, &( pFilePath[( ::wcslen( pFilePath ) - 4 )] ) );
	::_wcsupr_s( fileExt, 5 );

	if( ::wcscmp( fileExt, L".BMP" ) != 0 )
	{
		//ビットマップでしか保存できない
		return False;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_pBackBuffer->GetDesc( &bbDesc );

	MIX_ASSERT( bbDesc.Format == DXGI_FORMAT_R8G8B8A8_UNORM );

	ssDesc.ArraySize = 1;
	ssDesc.BindFlags = 0;
	ssDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
	ssDesc.Format = bbDesc.Format;
	ssDesc.Height = bbDesc.Height;
	ssDesc.Width = bbDesc.Width;
	ssDesc.MipLevels = 1;
	ssDesc.MiscFlags = 0;
	ssDesc.SampleDesc.Count = 1;
	ssDesc.SampleDesc.Quality = 0;
	ssDesc.Usage = D3D11_USAGE_STAGING;

	if( m_pD3DDevice->CreateTexture2D( &ssDesc, 0, &pTex ) == S_OK )
	{
		ID3D11Resource* pRes;

		m_pBackBufferView->GetResource( &pRes );
		m_pD3DDeviceContext->CopyResource( pTex, pRes );

		MIX_RELEASE( pRes );
	}
	else
	{
		return False;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////

	imgByteSize = bbDesc.Width * bbDesc.Height * 4;

	pImage = reinterpret_cast<UInt32*>( MIX_LIB_MALLOC( Mix::Memory::SECTION_GRAPHICS, imgByteSize ) );
	if( pImage == NULL )
	{
		MIX_RELEASE( pTex );
		return False;
	}

	if( m_pD3DDeviceContext->Map( pTex, 0, D3D11_MAP_READ, 0, &mappedSubRes ) == S_OK )
	{
		UInt32 imgBytePitch = bbDesc.Width * 4;
		UInt32 srcPitch = mappedSubRes.RowPitch / 4;

		UInt32* pSrcBegin = reinterpret_cast<UInt32*>( mappedSubRes.pData );
		UInt32* pDstBegin = pImage + ( bbDesc.Width * bbDesc.Height ) - bbDesc.Width;

		UInt32* pSrc;
		UInt32* pSrcEnd;
		UInt32* pDst;

		for( UInt32 i = 0; i < bbDesc.Height; i++ )
		{
			pSrc = pSrcBegin;
			pSrcEnd = pSrc + bbDesc.Width;

			pDst = pDstBegin;

			while( pSrc != pSrcEnd )
			{
				UInt32 r = ( *pSrc & 0x00FF0000 ) >> 16;
				UInt32 g = ( *pSrc & 0x0000FF00 ) >> 8;
				UInt32 b = ( *pSrc & 0x000000FF );

				*pDst++ = ( b << 16 ) | ( g << 8 ) | r;

				pSrc++;
			}

			pSrcBegin += srcPitch;
			pDstBegin -= bbDesc.Width;
		}

		m_pD3DDeviceContext->Unmap( pTex, 0 );
	}
	else
	{
		MIX_LIB_FREE( pImage );
		MIX_RELEASE( pTex );
		return False;
	}

	MIX_RELEASE( pTex );

	////////////////////////////////////////////////////////////////////////////////////////////////////

	bmpFileHeader.bfType = 0x4D42; //BM
	bmpFileHeader.bfSize = sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPCOREHEADER ) + imgByteSize;
	bmpFileHeader.bfReserved1 = 0;
	bmpFileHeader.bfReserved2 = 0;
	bmpFileHeader.bfOffBits = sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPCOREHEADER );

	bmpCoreHeader.bcSize = sizeof( BITMAPCOREHEADER );
	bmpCoreHeader.bcWidth = bbDesc.Width;
	bmpCoreHeader.bcHeight = bbDesc.Height;
	bmpCoreHeader.bcPlanes = 1;
	bmpCoreHeader.bcBitCount = 32;

	////////////////////////////////////////////////////////////////////////////////////////////////////

	hFile = CreateFile( pFilePath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
	if( hFile == INVALID_HANDLE_VALUE )
	{
		MIX_LIB_FREE( pImage );
		MIX_RELEASE( pTex );
		return False;
	}

	if( WriteFile( hFile, &bmpFileHeader, sizeof( BITMAPFILEHEADER ), &writeSize, NULL ) == FALSE )
	{
		CloseHandle( hFile );
		MIX_LIB_FREE( pImage );
		MIX_RELEASE( pTex );
		return False;
	}

	if( WriteFile( hFile, &bmpCoreHeader, sizeof( BITMAPCOREHEADER ), &writeSize, NULL ) == FALSE )
	{
		CloseHandle( hFile );
		MIX_LIB_FREE( pImage );
		MIX_RELEASE( pTex );
		return False;
	}

	if( WriteFile( hFile, pImage, imgByteSize, &writeSize, NULL ) == FALSE )
	{
		CloseHandle( hFile );
		MIX_LIB_FREE( pImage );
		MIX_RELEASE( pTex );
		return False;
	}

	CloseHandle( hFile );

	////////////////////////////////////////////////////////////////////////////////////////////////////

	MIX_LIB_FREE( pImage );

	MIX_LOG_INFO( L"%s : %s[%s]", SAVE_SCREEN_SHOT, Mix::STR_FILEPATH, pFilePath );

	////////////////////////////////////////////////////////////////////////////////////////////////////

	return True;
}

const Mix::Point& Device::GetScreenSize( void ) const
{
	return m_ScreenSize;
}

const Mix::Rectangle& Device::GetScreenValidBounds( void ) const
{
	return m_ScreenValidBounds;
}

UInt32 Device::GetDrawPrimitiveCount( void ) const
{
	return m_DrawPrimitiveCount;
}

Mix::Graphics::SHADER_MODEL Device::GetShaderModel( void ) const
{
	return m_ShaderModel;
}

void Device::UpdateScreenValidRect( void )
{
	D3D11_TEXTURE2D_DESC tex2DDesc;

	m_pBackBuffer->GetDesc( &tex2DDesc );

	m_ScreenValidBounds.x = ( m_ScreenSize.x - tex2DDesc.Width ) >> 1;
	m_ScreenValidBounds.y = ( m_ScreenSize.y - tex2DDesc.Height ) >> 1;
	m_ScreenValidBounds.width = tex2DDesc.Width;
	m_ScreenValidBounds.height = tex2DDesc.Height;
}

HRESULT Device::CreateBackBuffer( const wchar_t* failedMsg )
{
	ID3D11RenderTargetView* rtvTable[1];
	HRESULT ret;

	// バックバッファに関係するリソースの作成 //

	ret = m_pDXGISwapChain->GetBuffer( 0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>( &m_pBackBuffer ) );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : IDXGISwapChain::GetBuffer %s ( CreateBackBuffer ) : Result[%s]", failedMsg, Mix::STR_RETERROR, GetD3DResultText( ret ) );
		return ret;
	}

	ret = m_pD3DDevice->CreateRenderTargetView( m_pBackBuffer, NULL, &m_pBackBufferView );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : ID3D11Device::CreateRenderTargetView %s ( CreateBackBuffer ) : Result[%s]", failedMsg, Mix::STR_RETERROR, GetD3DResultText( ret ) );
		return ret;
	}

	m_pD3DDeviceContext->ClearRenderTargetView( m_pBackBufferView, Mix::Vector4::Zero().data );

	rtvTable[0] = m_pBackBufferView;
	m_pD3DDeviceContext->OMSetRenderTargets( 1, rtvTable, NULL );

	// 可変サイズウィンドウの IDXGISwapChain::Present 用のリソースの作成 //

	if( m_pEngine->IsSizeableWindow() == True )
	{
		D3D11_MAPPED_SUBRESOURCE vbMapped;
		Device::PRESENT_VERTEX* pv;
		D3D11_TEXTURE2D_DESC bbDesc;
		Float32 sw, sh;
		Float32 sx, sy, sxx, syy;

		ret = m_pD3DDeviceContext->Map( m_pPresentVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &vbMapped );
		if( ret != S_OK )
		{
			MIX_LOG_ERROR( L"%s : ID3D11DeviceContext::Map %s ( CreateBackBuffer - Present ) : Result[%s]", failedMsg, Mix::STR_RETERROR, GetD3DResultText( ret ) );
		}

		pv = static_cast<Device::PRESENT_VERTEX*>( vbMapped.pData );

		m_pBackBuffer->GetDesc( &bbDesc );

		sw = MIX_FLOAT_RECIPROCAL( static_cast<Float32>( m_ScreenSize.x ) );
		sh = MIX_FLOAT_RECIPROCAL( static_cast<Float32>( m_ScreenSize.y ) );

		sx = static_cast<Float32>( ( m_ScreenSize.x - bbDesc.Width ) >> 1 ) * sw;
		sy = static_cast<Float32>( ( m_ScreenSize.y - bbDesc.Height ) >> 1 ) * sh;
		sxx = sx + static_cast<Float32>( bbDesc.Width ) * sw;
		syy = sy + static_cast<Float32>( bbDesc.Height ) * sh;

		pv[0].pos.Set( -1.0f, +1.0f, 0.0f, 1.0f );
		pv[0].tex.Set( sx, sy );

		pv[1].pos.Set( +1.0f, +1.0f, 0.0f, 1.0f );
		pv[1].tex.Set( sxx, sy );

		pv[2].pos.Set( -1.0f, -1.0f, 0.0f, 1.0f );
		pv[2].tex.Set( sx, syy );

		pv[3].pos.Set( +1.0f, -1.0f, 0.0f, 1.0f );
		pv[3].tex.Set( sxx, syy );

		m_pD3DDeviceContext->Unmap( m_pPresentVB, 0 );
	}

	// 有効なスクリーン矩形の更新 //

	UpdateScreenValidRect();

	return S_OK;
}

Boolean Device::ResizeBackBuffer( void )
{
	Mix::Point clientSize = m_pEngine->GetClientSize();

	DXGI_SWAP_CHAIN_DESC scDesc;
	HRESULT ret;

	// 解放 //

	MIX_RELEASE( m_pBackBufferView );
	MIX_RELEASE( m_pBackBuffer );

	// リサイズ //

	ret = m_pDXGISwapChain->GetDesc( &scDesc );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : IDXGISwapChain::GetDesc %s : %s[%s]", FAILED_RESIZE_BACKBUFFER,
			Mix::STR_RETERROR, Mix::STR_RESULT, GetD3DResultText( ret ) );

		return False;
	}

	scDesc.BufferDesc.Width = clientSize.x;
	scDesc.BufferDesc.Height = clientSize.y;

	ret = m_pDXGISwapChain->ResizeBuffers(	scDesc.BufferCount,
											scDesc.BufferDesc.Width,
											scDesc.BufferDesc.Height,
											scDesc.BufferDesc.Format,
											scDesc.Flags );
	if( ret != S_OK )
	{
		MIX_LOG_ERROR( L"%s : IDXGISwapChain::ResizeBuffers %s : %s[%s]", FAILED_RESIZE_BACKBUFFER,
			Mix::STR_RETERROR, Mix::STR_RESULT, GetD3DResultText( ret ) );

		return False;
	}

	// 作成 //

	if( CreateBackBuffer( FAILED_RESIZE_BACKBUFFER ) != S_OK )
	{
		return False;
	}

	return True;
}

void Device::ResetTargetState( void )
{
	ID3D11ShaderResourceView* srvTable[Mix::Graphics::TARGET_MAX] = { NULL, NULL, NULL, NULL };
	ID3D11RenderTargetView* rtvTable[Mix::Graphics::TARGET_MAX] = { m_pBackBufferView, NULL, NULL, NULL };

	m_TargetState.rect = Mix::Rectangle( 0, 0, m_ScreenSize.x, m_ScreenSize.y );

	MIX_RELEASE( m_TargetState.pT0 );
	MIX_RELEASE( m_TargetState.pT1 );
	MIX_RELEASE( m_TargetState.pT2 );
	MIX_RELEASE( m_TargetState.pT3 );
	MIX_RELEASE( m_TargetState.pDS );

	m_pD3DDeviceContext->PSSetShaderResources( 0, Mix::Graphics::TARGET_MAX, srvTable );
	m_pD3DDeviceContext->OMSetRenderTargets( Mix::Graphics::TARGET_MAX, rtvTable, NULL );
}

void Device::ResetDrawState( void )
{
	UInt32 i;

	for( i = 0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++ )
	{
		m_DrawState.hscTable[i] = NULL;
		m_DrawState.dscTable[i] = NULL;
		m_DrawState.gscTable[i] = NULL;
		m_DrawState.vscTable[i] = NULL;
		m_DrawState.pscTable[i] = NULL;
	}

	for( i = 0; i < Mix::Graphics::TEXTURESTAGE_MAX; i++ )
	{
		m_DrawState.samplerTable[i] = NULL;
		m_DrawState.textureTable[i] = NULL;
	}

	m_DrawState.current.pVertexLayout = NULL;
	m_DrawState.current.pHullShader = NULL;
	m_DrawState.current.pDomainShader = NULL;
	m_DrawState.current.pGeometryShader = NULL;
	m_DrawState.current.pVertexShader = NULL;
	m_DrawState.current.pPixelShader = NULL;
	m_DrawState.current.pVertexBuffer = NULL;
	m_DrawState.current.pIndexBuffer = NULL;
	m_DrawState.next.pVertexLayout = NULL;
	m_DrawState.next.pHullShader = NULL;
	m_DrawState.next.pDomainShader = NULL;
	m_DrawState.next.pGeometryShader = NULL;
	m_DrawState.next.pVertexShader = NULL;
	m_DrawState.next.pPixelShader = NULL;
	m_DrawState.next.pVertexBuffer = NULL;
	m_DrawState.next.pIndexBuffer = NULL;
}

void Device::FlushDrawState( UInt32 startVertex, UInt32 startIndex )
{
	//バーテックスレイアウト
	if( m_DrawState.current.pVertexLayout != m_DrawState.next.pVertexLayout )
	{
		m_pD3DDeviceContext->IASetInputLayout( static_cast<Mix::Graphics::DX11::VertexLayout*>( m_DrawState.next.pVertexLayout )->GetInterface() );
		m_DrawState.current.pVertexLayout = m_DrawState.next.pVertexLayout;
	}

	//ハルシェーダー
	if( m_DrawState.current.pHullShader != m_DrawState.next.pHullShader )
	{
		if( m_DrawState.next.pHullShader != NULL )
		{
			m_pD3DDeviceContext->HSSetShader( static_cast<Mix::Graphics::DX11::HullShader*>( m_DrawState.next.pHullShader )->GetInterface(), NULL, 0 );
		}
		else
		{
			m_pD3DDeviceContext->HSSetShader( NULL, NULL, 0 );
		}

		m_DrawState.current.pHullShader = m_DrawState.next.pHullShader;
	}

	//ドメインシェーダー
	if( m_DrawState.current.pDomainShader != m_DrawState.next.pDomainShader )
	{
		if( m_DrawState.next.pDomainShader != NULL )
		{
			m_pD3DDeviceContext->DSSetShader( static_cast<Mix::Graphics::DX11::DomainShader*>( m_DrawState.next.pDomainShader )->GetInterface(), NULL, 0 );
		}
		else
		{
			m_pD3DDeviceContext->DSSetShader( NULL, NULL, 0 );
		}

		m_DrawState.current.pDomainShader = m_DrawState.next.pDomainShader;
	}

	//ジオメトリシェーダー
	if( m_DrawState.current.pGeometryShader != m_DrawState.next.pGeometryShader )
	{
		if( m_DrawState.next.pGeometryShader != NULL )
		{
			m_pD3DDeviceContext->GSSetShader( static_cast<Mix::Graphics::DX11::GeometryShader*>( m_DrawState.next.pGeometryShader )->GetInterface(), NULL, 0 );
		}
		else
		{
			m_pD3DDeviceContext->GSSetShader( NULL, NULL, 0 );
		}

		m_DrawState.current.pGeometryShader = m_DrawState.next.pGeometryShader;
	}

	//バーテックスシェーダー
	if( m_DrawState.current.pVertexShader != m_DrawState.next.pVertexShader )
	{
		m_pD3DDeviceContext->VSSetShader( static_cast<Mix::Graphics::DX11::VertexShader*>( m_DrawState.next.pVertexShader )->GetInterface(), NULL, 0 );
		m_DrawState.current.pVertexShader = m_DrawState.next.pVertexShader;
	}

	//ピクセルシェーダー
	if( m_DrawState.current.pPixelShader != m_DrawState.next.pPixelShader )
	{
		m_pD3DDeviceContext->PSSetShader( static_cast<Mix::Graphics::DX11::PixelShader*>( m_DrawState.next.pPixelShader )->GetInterface(), NULL, 0 );
		m_DrawState.current.pPixelShader = m_DrawState.next.pPixelShader;
	}

	//バーテックスバッファ
	if( m_DrawState.current.pVertexBuffer != m_DrawState.next.pVertexBuffer )
	{
		ID3D11Buffer* bufferTable[1] = { static_cast<Mix::Graphics::DX11::VertexBuffer*>( m_DrawState.next.pVertexBuffer )->GetInsterface() };
		UInt32 strideTable[1] = { m_DrawState.next.pVertexBuffer->GetStride() };
		UInt32 offsetTable[1] = { 0 };

		m_pD3DDeviceContext->IASetVertexBuffers( 0,	1, bufferTable, strideTable, offsetTable );
		m_DrawState.current.pVertexBuffer = m_DrawState.next.pVertexBuffer;
	}

	//インデックスバッファ
	if( (  m_DrawState.next.pIndexBuffer != NULL ) &&
		( m_DrawState.current.pIndexBuffer != m_DrawState.next.pIndexBuffer ) )
	{
		Mix::Graphics::DX11::IndexBuffer* pIndexBuffer = static_cast<Mix::Graphics::DX11::IndexBuffer*>( m_DrawState.next.pIndexBuffer );
		Mix::Graphics::INDEX_FORMAT indexFormat = pIndexBuffer->GetFormat();

		m_pD3DDeviceContext->IASetIndexBuffer(	pIndexBuffer->GetInterface(),
												Device::D3DIndexFormatTable[indexFormat],
												0 );//( startIndex * Device::D3DIndexStrideTable[indexType] ) );

		m_DrawState.current.pIndexBuffer = m_DrawState.next.pIndexBuffer;
	}
}

UInt32 Device::ComputePrimitiveCount( Mix::Graphics::PRIMITIVE_TYPE type, UInt32 num )
{
	UInt32 count = 0;

	switch( type )
	{
	case PRIMITIVE_POINTLIST:
		count = num;
		break;
	case PRIMITIVE_LINELIST:
		count = ( num >> 1 );
		break;
	case PRIMITIVE_LINESTRIP:
		if( num >= 2 )
		{
			count = ( num - 1 );
		}
		break;
	case PRIMITIVE_TRIANGLELIST:
		count = ( num / 3 );
		break;
	case PRIMITIVE_TRIANGLESTRIP:
		if( num >= 3 )
		{
			count = ( num - 2 );
		}
		break;
	}

	return count;
}

}}}
