2010-04-25 00:31:27 +00:00
/*
2010-01-28 13:07:06 +00:00
* Copyright ( C ) 2007 - 2009 Gabest
* http : //www.gabest.org
*
* This Program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 , or ( at your option )
* any later version .
2010-04-25 00:31:27 +00:00
*
2010-01-28 13:07:06 +00:00
* This Program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
2010-04-25 00:31:27 +00:00
*
2010-01-28 13:07:06 +00:00
* You should have received a copy of the GNU General Public License
* along with GNU Make ; see the file COPYING . If not , write to
2012-09-09 18:16:11 +00:00
* the Free Software Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 , USA USA .
2010-01-28 13:07:06 +00:00
* http : //www.gnu.org/copyleft/gpl.html
*
*/
# include "stdafx.h"
# include "GSdx.h"
# include "GSDevice11.h"
2010-05-07 14:19:54 +00:00
# include "GSUtil.h"
2010-01-28 13:07:06 +00:00
# include "resource.h"
2015-08-29 15:53:29 +00:00
# include <fstream>
2010-01-28 13:07:06 +00:00
GSDevice11 : : GSDevice11 ( )
{
memset ( & m_state , 0 , sizeof ( m_state ) ) ;
memset ( & m_vs_cb_cache , 0 , sizeof ( m_vs_cb_cache ) ) ;
memset ( & m_ps_cb_cache , 0 , sizeof ( m_ps_cb_cache ) ) ;
2014-02-02 17:50:32 +00:00
FXAA_Compiled = false ;
ExShader_Compiled = false ;
2015-05-28 20:41:02 +00:00
2010-01-28 13:07:06 +00:00
m_state . topology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED ;
m_state . bf = - 1 ;
}
GSDevice11 : : ~ GSDevice11 ( )
{
}
bool GSDevice11 : : Create ( GSWnd * wnd )
{
if ( ! __super : : Create ( wnd ) )
{
return false ;
}
HRESULT hr = E_FAIL ;
DXGI_SWAP_CHAIN_DESC scd ;
D3D11_BUFFER_DESC bd ;
D3D11_SAMPLER_DESC sd ;
D3D11_DEPTH_STENCIL_DESC dsd ;
2011-02-24 23:46:26 +00:00
D3D11_RASTERIZER_DESC rd ;
2010-01-28 13:07:06 +00:00
D3D11_BLEND_DESC bsd ;
2012-08-06 05:26:44 +00:00
CComPtr < IDXGIAdapter1 > adapter ;
D3D_DRIVER_TYPE driver_type = D3D_DRIVER_TYPE_HARDWARE ;
std : : string adapter_id = theApp . GetConfig ( " Adapter " , " default " ) ;
if ( adapter_id = = " default " )
;
else if ( adapter_id = = " ref " )
{
driver_type = D3D_DRIVER_TYPE_REFERENCE ;
}
else
{
CComPtr < IDXGIFactory1 > dxgi_factory ;
CreateDXGIFactory1 ( __uuidof ( IDXGIFactory1 ) , ( void * * ) & dxgi_factory ) ;
if ( dxgi_factory )
for ( int i = 0 ; ; i + + )
{
CComPtr < IDXGIAdapter1 > enum_adapter ;
if ( S_OK ! = dxgi_factory - > EnumAdapters1 ( i , & enum_adapter ) )
break ;
DXGI_ADAPTER_DESC1 desc ;
hr = enum_adapter - > GetDesc1 ( & desc ) ;
if ( S_OK = = hr & & GSAdapter ( desc ) = = adapter_id )
{
adapter = enum_adapter ;
driver_type = D3D_DRIVER_TYPE_UNKNOWN ;
break ;
}
}
}
2010-01-28 13:07:06 +00:00
memset ( & scd , 0 , sizeof ( scd ) ) ;
scd . BufferCount = 2 ;
scd . BufferDesc . Width = 1 ;
scd . BufferDesc . Height = 1 ;
scd . BufferDesc . Format = DXGI_FORMAT_R8G8B8A8_UNORM ;
//scd.BufferDesc.RefreshRate.Numerator = 60;
//scd.BufferDesc.RefreshRate.Denominator = 1;
scd . BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT ;
2011-02-19 03:36:30 +00:00
scd . OutputWindow = ( HWND ) m_wnd - > GetHandle ( ) ;
2010-01-28 13:07:06 +00:00
scd . SampleDesc . Count = 1 ;
scd . SampleDesc . Quality = 0 ;
2010-03-19 20:27:06 +00:00
// Always start in Windowed mode. According to MS, DXGI just "prefers" this, and it's more or less
// required if we want to add support for dual displays later on. The fullscreen/exclusive flip
// will be issued after all other initializations are complete.
2010-01-28 13:07:06 +00:00
scd . Windowed = TRUE ;
2015-11-10 22:58:43 +00:00
spritehack = ! ! theApp . GetConfig ( " UserHacks " , 0 ) ? theApp . GetConfig ( " UserHacks_SpriteHack " , 0 ) : 0 ;
2010-03-19 20:27:06 +00:00
// NOTE : D3D11_CREATE_DEVICE_SINGLETHREADED
// This flag is safe as long as the DXGI's internal message pump is disabled or is on the
// same thread as the GS window (which the emulator makes sure of, if it utilizes a
// multithreaded GS). Setting the flag is a nice and easy 5% speedup on GS-intensive scenes.
2010-01-28 13:07:06 +00:00
uint32 flags = D3D11_CREATE_DEVICE_SINGLETHREADED ;
# ifdef DEBUG
flags | = D3D11_CREATE_DEVICE_DEBUG ;
# endif
D3D_FEATURE_LEVEL level ;
2011-02-20 16:09:46 +00:00
const D3D_FEATURE_LEVEL levels [ ] =
{
D3D_FEATURE_LEVEL_11_0 ,
D3D_FEATURE_LEVEL_10_1 ,
D3D_FEATURE_LEVEL_10_0 ,
} ;
2012-08-06 05:26:44 +00:00
hr = D3D11CreateDeviceAndSwapChain ( adapter , driver_type , NULL , flags , levels , countof ( levels ) , D3D11_SDK_VERSION , & scd , & m_swapchain , & m_dev , & level , & m_ctx ) ;
2010-01-28 13:07:06 +00:00
if ( FAILED ( hr ) ) return false ;
if ( ! SetFeatureLevel ( level , true ) )
{
return false ;
}
D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS options ;
2010-04-25 00:31:27 +00:00
2010-01-28 13:07:06 +00:00
hr = m_dev - > CheckFeatureSupport ( D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS , & options , sizeof ( D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS ) ) ;
// msaa
for ( uint32 i = 2 ; i < = D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT ; i + + )
{
uint32 quality [ 2 ] = { 0 , 0 } ;
if ( SUCCEEDED ( m_dev - > CheckMultisampleQualityLevels ( DXGI_FORMAT_R8G8B8A8_UNORM , i , & quality [ 0 ] ) ) & & quality [ 0 ] > 0
& & SUCCEEDED ( m_dev - > CheckMultisampleQualityLevels ( DXGI_FORMAT_D32_FLOAT_S8X24_UINT , i , & quality [ 1 ] ) ) & & quality [ 1 ] > 0 )
{
m_msaa_desc . Count = i ;
m_msaa_desc . Quality = std : : min < uint32 > ( quality [ 0 ] - 1 , quality [ 1 ] - 1 ) ;
if ( i > = m_msaa ) break ;
}
}
2011-02-07 01:59:05 +00:00
if ( m_msaa_desc . Count = = 1 )
{
2010-12-17 01:32:40 +00:00
m_msaa = 0 ;
2011-02-07 01:59:05 +00:00
}
2010-12-17 01:32:40 +00:00
2010-01-28 13:07:06 +00:00
// convert
D3D11_INPUT_ELEMENT_DESC il_convert [ ] =
{
{ " POSITION " , 0 , DXGI_FORMAT_R32G32B32A32_FLOAT , 0 , 0 , D3D11_INPUT_PER_VERTEX_DATA , 0 } ,
{ " TEXCOORD " , 0 , DXGI_FORMAT_R32G32_FLOAT , 0 , 16 , D3D11_INPUT_PER_VERTEX_DATA , 0 } ,
} ;
2015-08-29 15:53:29 +00:00
vector < unsigned char > shader ;
theApp . LoadResource ( IDR_CONVERT_FX , shader ) ;
CompileShader ( ( const char * ) shader . data ( ) , shader . size ( ) , " convert.fx " , " vs_main " , NULL , & m_convert . vs , il_convert , countof ( il_convert ) , & m_convert . il ) ;
2010-01-28 13:07:06 +00:00
2013-06-29 12:02:03 +00:00
for ( size_t i = 0 ; i < countof ( m_convert . ps ) ; i + + )
2010-01-28 13:07:06 +00:00
{
2015-08-29 15:53:29 +00:00
CompileShader ( ( const char * ) shader . data ( ) , shader . size ( ) , " convert.fx " , format ( " ps_main%d " , i ) . c_str ( ) , NULL , & m_convert . ps [ i ] ) ;
2010-01-28 13:07:06 +00:00
}
memset ( & dsd , 0 , sizeof ( dsd ) ) ;
dsd . DepthEnable = false ;
dsd . StencilEnable = false ;
hr = m_dev - > CreateDepthStencilState ( & dsd , & m_convert . dss ) ;
memset ( & bsd , 0 , sizeof ( bsd ) ) ;
bsd . RenderTarget [ 0 ] . RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL ;
hr = m_dev - > CreateBlendState ( & bsd , & m_convert . bs ) ;
// merge
memset ( & bd , 0 , sizeof ( bd ) ) ;
2011-02-24 23:46:26 +00:00
bd . ByteWidth = sizeof ( MergeConstantBuffer ) ;
bd . Usage = D3D11_USAGE_DEFAULT ;
bd . BindFlags = D3D11_BIND_CONSTANT_BUFFER ;
2010-01-28 13:07:06 +00:00
2011-02-24 23:46:26 +00:00
hr = m_dev - > CreateBuffer ( & bd , NULL , & m_merge . cb ) ;
2010-01-28 13:07:06 +00:00
2015-08-29 15:53:29 +00:00
theApp . LoadResource ( IDR_MERGE_FX , shader ) ;
2013-06-29 12:02:03 +00:00
for ( size_t i = 0 ; i < countof ( m_merge . ps ) ; i + + )
2010-01-28 13:07:06 +00:00
{
2015-08-29 15:53:29 +00:00
CompileShader ( ( const char * ) shader . data ( ) , shader . size ( ) , " merge.fx " , format ( " ps_main%d " , i ) . c_str ( ) , NULL , & m_merge . ps [ i ] ) ;
2010-01-28 13:07:06 +00:00
}
memset ( & bsd , 0 , sizeof ( bsd ) ) ;
bsd . RenderTarget [ 0 ] . BlendEnable = true ;
bsd . RenderTarget [ 0 ] . BlendOp = D3D11_BLEND_OP_ADD ;
bsd . RenderTarget [ 0 ] . SrcBlend = D3D11_BLEND_SRC_ALPHA ;
bsd . RenderTarget [ 0 ] . DestBlend = D3D11_BLEND_INV_SRC_ALPHA ;
bsd . RenderTarget [ 0 ] . BlendOpAlpha = D3D11_BLEND_OP_ADD ;
bsd . RenderTarget [ 0 ] . SrcBlendAlpha = D3D11_BLEND_ONE ;
bsd . RenderTarget [ 0 ] . DestBlendAlpha = D3D11_BLEND_ZERO ;
bsd . RenderTarget [ 0 ] . RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL ;
hr = m_dev - > CreateBlendState ( & bsd , & m_merge . bs ) ;
// interlace
memset ( & bd , 0 , sizeof ( bd ) ) ;
2011-02-24 23:46:26 +00:00
bd . ByteWidth = sizeof ( InterlaceConstantBuffer ) ;
bd . Usage = D3D11_USAGE_DEFAULT ;
bd . BindFlags = D3D11_BIND_CONSTANT_BUFFER ;
2010-01-28 13:07:06 +00:00
2011-02-24 23:46:26 +00:00
hr = m_dev - > CreateBuffer ( & bd , NULL , & m_interlace . cb ) ;
2010-01-28 13:07:06 +00:00
2015-08-29 15:53:29 +00:00
theApp . LoadResource ( IDR_INTERLACE_FX , shader ) ;
2013-06-29 12:02:03 +00:00
for ( size_t i = 0 ; i < countof ( m_interlace . ps ) ; i + + )
2010-01-28 13:07:06 +00:00
{
2015-08-29 15:53:29 +00:00
CompileShader ( ( const char * ) shader . data ( ) , shader . size ( ) , " interlace.fx " , format ( " ps_main%d " , i ) . c_str ( ) , NULL , & m_interlace . ps [ i ] ) ;
2010-01-28 13:07:06 +00:00
}
2012-02-29 00:29:29 +00:00
// Shade Boost
int ShadeBoost_Contrast = theApp . GetConfig ( " ShadeBoost_Contrast " , 50 ) ;
int ShadeBoost_Brightness = theApp . GetConfig ( " ShadeBoost_Brightness " , 50 ) ;
int ShadeBoost_Saturation = theApp . GetConfig ( " ShadeBoost_Saturation " , 50 ) ;
string str [ 3 ] ;
str [ 0 ] = format ( " %d " , ShadeBoost_Saturation ) ;
str [ 1 ] = format ( " %d " , ShadeBoost_Brightness ) ;
str [ 2 ] = format ( " %d " , ShadeBoost_Contrast ) ;
D3D11_SHADER_MACRO macro [ ] =
{
{ " SB_SATURATION " , str [ 0 ] . c_str ( ) } ,
{ " SB_BRIGHTNESS " , str [ 1 ] . c_str ( ) } ,
{ " SB_CONTRAST " , str [ 2 ] . c_str ( ) } ,
{ NULL , NULL } ,
} ;
memset ( & bd , 0 , sizeof ( bd ) ) ;
bd . ByteWidth = sizeof ( ShadeBoostConstantBuffer ) ;
bd . Usage = D3D11_USAGE_DEFAULT ;
bd . BindFlags = D3D11_BIND_CONSTANT_BUFFER ;
hr = m_dev - > CreateBuffer ( & bd , NULL , & m_shadeboost . cb ) ;
2015-08-29 15:53:29 +00:00
theApp . LoadResource ( IDR_SHADEBOOST_FX , shader ) ;
CompileShader ( ( const char * ) shader . data ( ) , shader . size ( ) , " shadeboost.fx " , " ps_main " , macro , & m_shadeboost . ps ) ;
2012-02-29 00:29:29 +00:00
2014-01-17 10:17:24 +00:00
// External fx shader
memset ( & bd , 0 , sizeof ( bd ) ) ;
bd . ByteWidth = sizeof ( ExternalFXConstantBuffer ) ;
bd . Usage = D3D11_USAGE_DEFAULT ;
bd . BindFlags = D3D11_BIND_CONSTANT_BUFFER ;
hr = m_dev - > CreateBuffer ( & bd , NULL , & m_shaderfx . cb ) ;
// Fxaa
2011-07-25 11:16:01 +00:00
memset ( & bd , 0 , sizeof ( bd ) ) ;
bd . ByteWidth = sizeof ( FXAAConstantBuffer ) ;
bd . Usage = D3D11_USAGE_DEFAULT ;
bd . BindFlags = D3D11_BIND_CONSTANT_BUFFER ;
hr = m_dev - > CreateBuffer ( & bd , NULL , & m_fxaa . cb ) ;
2014-02-02 17:50:32 +00:00
//
2010-01-28 13:07:06 +00:00
memset ( & rd , 0 , sizeof ( rd ) ) ;
rd . FillMode = D3D11_FILL_SOLID ;
rd . CullMode = D3D11_CULL_NONE ;
rd . FrontCounterClockwise = false ;
rd . DepthBias = false ;
rd . DepthBiasClamp = 0 ;
rd . SlopeScaledDepthBias = 0 ;
rd . DepthClipEnable = false ; // ???
rd . ScissorEnable = true ;
rd . MultisampleEnable = true ;
rd . AntialiasedLineEnable = false ;
hr = m_dev - > CreateRasterizerState ( & rd , & m_rs ) ;
m_ctx - > RSSetState ( m_rs ) ;
//
memset ( & sd , 0 , sizeof ( sd ) ) ;
2015-08-11 16:35:45 +00:00
sd . Filter = theApp . GetConfig ( " MaxAnisotropy " , 0 ) & & ! theApp . GetConfig ( " paltex " , 0 ) ? D3D11_FILTER_ANISOTROPIC : D3D11_FILTER_MIN_MAG_MIP_LINEAR ;
2010-01-28 13:07:06 +00:00
sd . AddressU = D3D11_TEXTURE_ADDRESS_CLAMP ;
sd . AddressV = D3D11_TEXTURE_ADDRESS_CLAMP ;
sd . AddressW = D3D11_TEXTURE_ADDRESS_CLAMP ;
2014-02-04 21:42:43 +00:00
sd . MinLOD = - FLT_MAX ;
2010-01-28 13:07:06 +00:00
sd . MaxLOD = FLT_MAX ;
2014-02-03 16:58:11 +00:00
sd . MaxAnisotropy = theApp . GetConfig ( " MaxAnisotropy " , 0 ) ;
2010-01-28 13:07:06 +00:00
sd . ComparisonFunc = D3D11_COMPARISON_NEVER ;
hr = m_dev - > CreateSamplerState ( & sd , & m_convert . ln ) ;
2015-08-11 16:35:45 +00:00
sd . Filter = theApp . GetConfig ( " MaxAnisotropy " , 0 ) & & ! theApp . GetConfig ( " paltex " , 0 ) ? D3D11_FILTER_ANISOTROPIC : D3D11_FILTER_MIN_MAG_MIP_POINT ;
2010-01-28 13:07:06 +00:00
hr = m_dev - > CreateSamplerState ( & sd , & m_convert . pt ) ;
//
Reset ( 1 , 1 ) ;
//
CreateTextureFX ( ) ;
2010-04-25 00:31:27 +00:00
2010-01-28 13:07:06 +00:00
//
memset ( & dsd , 0 , sizeof ( dsd ) ) ;
dsd . DepthEnable = false ;
dsd . StencilEnable = true ;
dsd . StencilReadMask = 1 ;
dsd . StencilWriteMask = 1 ;
dsd . FrontFace . StencilFunc = D3D11_COMPARISON_ALWAYS ;
dsd . FrontFace . StencilPassOp = D3D11_STENCIL_OP_REPLACE ;
dsd . FrontFace . StencilFailOp = D3D11_STENCIL_OP_KEEP ;
dsd . FrontFace . StencilDepthFailOp = D3D11_STENCIL_OP_KEEP ;
dsd . BackFace . StencilFunc = D3D11_COMPARISON_ALWAYS ;
dsd . BackFace . StencilPassOp = D3D11_STENCIL_OP_REPLACE ;
dsd . BackFace . StencilFailOp = D3D11_STENCIL_OP_KEEP ;
dsd . BackFace . StencilDepthFailOp = D3D11_STENCIL_OP_KEEP ;
m_dev - > CreateDepthStencilState ( & dsd , & m_date . dss ) ;
D3D11_BLEND_DESC blend ;
memset ( & blend , 0 , sizeof ( blend ) ) ;
m_dev - > CreateBlendState ( & blend , & m_date . bs ) ;
2010-03-19 20:27:06 +00:00
// Exclusive/Fullscreen flip, issued for legacy (managed) windows only. GSopen2 style
// emulators will issue the flip themselves later on.
2010-01-28 13:07:06 +00:00
if ( m_wnd - > IsManaged ( ) )
{
2011-02-25 01:01:00 +00:00
SetExclusive ( ! theApp . GetConfig ( " windowed " , 1 ) ) ;
2010-01-28 13:07:06 +00:00
}
return true ;
}
bool GSDevice11 : : Reset ( int w , int h )
{
if ( ! __super : : Reset ( w , h ) )
return false ;
if ( m_swapchain )
{
DXGI_SWAP_CHAIN_DESC scd ;
2011-02-22 23:39:02 +00:00
2010-01-28 13:07:06 +00:00
memset ( & scd , 0 , sizeof ( scd ) ) ;
2011-02-07 01:59:05 +00:00
2010-01-28 13:07:06 +00:00
m_swapchain - > GetDesc ( & scd ) ;
m_swapchain - > ResizeBuffers ( scd . BufferCount , w , h , scd . BufferDesc . Format , 0 ) ;
2010-04-25 00:31:27 +00:00
2010-01-28 13:07:06 +00:00
CComPtr < ID3D11Texture2D > backbuffer ;
2011-02-07 01:59:05 +00:00
2010-01-28 13:25:18 +00:00
if ( FAILED ( m_swapchain - > GetBuffer ( 0 , __uuidof ( ID3D11Texture2D ) , ( void * * ) & backbuffer ) ) )
2010-01-28 13:07:06 +00:00
{
2010-01-28 13:25:18 +00:00
return false ;
2010-01-28 13:07:06 +00:00
}
2010-01-28 13:25:18 +00:00
m_backbuffer = new GSTexture11 ( backbuffer ) ;
2010-01-28 13:07:06 +00:00
}
return true ;
}
void GSDevice11 : : SetExclusive ( bool isExcl )
{
if ( ! m_swapchain ) return ;
2010-04-25 00:31:27 +00:00
2010-01-28 13:07:06 +00:00
// TODO : Support for alternative display modes, by finishing this code below:
// Video mode info should be pulled form config/ini.
/*DXGI_MODE_DESC desc;
memset ( & desc , 0 , sizeof ( desc ) ) ;
desc . RefreshRate = 0 ; // must be zero for best results.
m_swapchain - > ResizeTarget ( & desc ) ;
*/
2010-04-25 00:31:27 +00:00
2011-02-07 01:59:05 +00:00
HRESULT hr = m_swapchain - > SetFullscreenState ( isExcl , NULL ) ;
2010-01-28 13:07:06 +00:00
if ( hr = = DXGI_ERROR_NOT_CURRENTLY_AVAILABLE )
2011-02-07 01:59:05 +00:00
{
2010-01-28 13:07:06 +00:00
fprintf ( stderr , " (GSdx10) SetExclusive(%s) failed; request unavailable. " , isExcl ? " true " : " false " ) ;
2011-02-07 01:59:05 +00:00
}
2010-04-25 00:31:27 +00:00
}
2010-01-28 13:07:06 +00:00
void GSDevice11 : : Flip ( )
{
m_swapchain - > Present ( m_vsync , 0 ) ;
}
void GSDevice11 : : DrawPrimitive ( )
{
2012-01-05 02:40:24 +00:00
m_ctx - > Draw ( m_vertex . count , m_vertex . start ) ;
}
void GSDevice11 : : DrawIndexedPrimitive ( )
{
m_ctx - > DrawIndexed ( m_index . count , m_index . start , m_vertex . start ) ;
2010-01-28 13:07:06 +00:00
}
2012-01-27 11:56:49 +00:00
void GSDevice11 : : DrawIndexedPrimitive ( int offset , int count )
{
ASSERT ( offset + count < = m_index . count ) ;
m_ctx - > DrawIndexed ( count , m_index . start + offset , m_vertex . start ) ;
}
2012-01-13 18:10:05 +00:00
void GSDevice11 : : Dispatch ( uint32 x , uint32 y , uint32 z )
{
m_ctx - > Dispatch ( x , y , z ) ;
}
2010-01-28 13:07:06 +00:00
void GSDevice11 : : ClearRenderTarget ( GSTexture * t , const GSVector4 & c )
{
2015-08-04 17:26:17 +00:00
if ( ! t ) return ;
2010-01-28 13:07:06 +00:00
m_ctx - > ClearRenderTargetView ( * ( GSTexture11 * ) t , c . v ) ;
}
void GSDevice11 : : ClearRenderTarget ( GSTexture * t , uint32 c )
{
2015-08-04 17:26:17 +00:00
if ( ! t ) return ;
2011-04-04 11:05:54 +00:00
GSVector4 color = GSVector4 : : rgba32 ( c ) * ( 1.0f / 255 ) ;
2010-01-28 13:07:06 +00:00
m_ctx - > ClearRenderTargetView ( * ( GSTexture11 * ) t , color . v ) ;
}
void GSDevice11 : : ClearDepth ( GSTexture * t , float c )
{
2015-08-04 17:26:17 +00:00
if ( ! t ) return ;
2010-01-28 13:07:06 +00:00
m_ctx - > ClearDepthStencilView ( * ( GSTexture11 * ) t , D3D11_CLEAR_DEPTH , c , 0 ) ;
}
void GSDevice11 : : ClearStencil ( GSTexture * t , uint8 c )
{
2015-08-04 17:26:17 +00:00
if ( ! t ) return ;
2010-01-28 13:07:06 +00:00
m_ctx - > ClearDepthStencilView ( * ( GSTexture11 * ) t , D3D11_CLEAR_STENCIL , 0 , c ) ;
}
2011-02-22 23:39:02 +00:00
GSTexture * GSDevice11 : : CreateSurface ( int type , int w , int h , bool msaa , int format )
2010-01-28 13:07:06 +00:00
{
HRESULT hr ;
D3D11_TEXTURE2D_DESC desc ;
memset ( & desc , 0 , sizeof ( desc ) ) ;
desc . Width = w ;
desc . Height = h ;
desc . Format = ( DXGI_FORMAT ) format ;
desc . MipLevels = 1 ;
desc . ArraySize = 1 ;
desc . SampleDesc . Count = 1 ;
desc . SampleDesc . Quality = 0 ;
desc . Usage = D3D11_USAGE_DEFAULT ;
2010-04-25 00:31:27 +00:00
if ( msaa )
2010-01-28 13:07:06 +00:00
{
desc . SampleDesc = m_msaa_desc ;
}
switch ( type )
{
case GSTexture : : RenderTarget :
desc . BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE ;
break ;
case GSTexture : : DepthStencil :
desc . BindFlags = D3D11_BIND_DEPTH_STENCIL ;
break ;
case GSTexture : : Texture :
desc . BindFlags = D3D11_BIND_SHADER_RESOURCE ;
break ;
case GSTexture : : Offscreen :
desc . Usage = D3D11_USAGE_STAGING ;
desc . CPUAccessFlags | = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE ;
break ;
}
GSTexture11 * t = NULL ;
CComPtr < ID3D11Texture2D > texture ;
hr = m_dev - > CreateTexture2D ( & desc , NULL , & texture ) ;
if ( SUCCEEDED ( hr ) )
{
t = new GSTexture11 ( texture ) ;
switch ( type )
{
case GSTexture : : RenderTarget :
ClearRenderTarget ( t , 0 ) ;
break ;
case GSTexture : : DepthStencil :
ClearDepth ( t , 0 ) ;
break ;
}
}
return t ;
}
GSTexture * GSDevice11 : : CreateRenderTarget ( int w , int h , bool msaa , int format )
{
return __super : : CreateRenderTarget ( w , h , msaa , format ? format : DXGI_FORMAT_R8G8B8A8_UNORM ) ;
}
GSTexture * GSDevice11 : : CreateDepthStencil ( int w , int h , bool msaa , int format )
{
2010-03-19 20:27:06 +00:00
return __super : : CreateDepthStencil ( w , h , msaa , format ? format : DXGI_FORMAT_D32_FLOAT_S8X24_UINT ) ; // DXGI_FORMAT_R32G8X24_TYPELESS
2010-01-28 13:07:06 +00:00
}
GSTexture * GSDevice11 : : CreateTexture ( int w , int h , int format )
{
return __super : : CreateTexture ( w , h , format ? format : DXGI_FORMAT_R8G8B8A8_UNORM ) ;
}
GSTexture * GSDevice11 : : CreateOffscreen ( int w , int h , int format )
{
return __super : : CreateOffscreen ( w , h , format ? format : DXGI_FORMAT_R8G8B8A8_UNORM ) ;
}
GSTexture * GSDevice11 : : Resolve ( GSTexture * t )
{
ASSERT ( t ! = NULL & & t - > IsMSAA ( ) ) ;
if ( GSTexture * dst = CreateRenderTarget ( t - > GetWidth ( ) , t - > GetHeight ( ) , false , t - > GetFormat ( ) ) )
{
dst - > SetScale ( t - > GetScale ( ) ) ;
m_ctx - > ResolveSubresource ( * ( GSTexture11 * ) dst , 0 , * ( GSTexture11 * ) t , 0 , ( DXGI_FORMAT ) t - > GetFormat ( ) ) ;
return dst ;
}
return NULL ;
}
2015-05-19 10:42:14 +00:00
GSTexture * GSDevice11 : : CopyOffscreen ( GSTexture * src , const GSVector4 & sRect , int w , int h , int format , int ps_shader )
2010-01-28 13:07:06 +00:00
{
GSTexture * dst = NULL ;
if ( format = = 0 )
{
format = DXGI_FORMAT_R8G8B8A8_UNORM ;
}
if ( format ! = DXGI_FORMAT_R8G8B8A8_UNORM & & format ! = DXGI_FORMAT_R16_UINT )
{
ASSERT ( 0 ) ;
return false ;
}
if ( GSTexture * rt = CreateRenderTarget ( w , h , false , format ) )
{
2015-05-15 18:49:25 +00:00
GSVector4 dRect ( 0 , 0 , w , h ) ;
2010-01-28 13:07:06 +00:00
if ( GSTexture * src2 = src - > IsMSAA ( ) ? Resolve ( src ) : src )
{
2015-05-15 18:49:25 +00:00
StretchRect ( src2 , sRect , rt , dRect , m_convert . ps [ format = = DXGI_FORMAT_R16_UINT ? 1 : 0 ] , NULL ) ;
2010-01-28 13:07:06 +00:00
if ( src2 ! = src ) Recycle ( src2 ) ;
}
dst = CreateOffscreen ( w , h , format ) ;
if ( dst )
{
m_ctx - > CopyResource ( * ( GSTexture11 * ) dst , * ( GSTexture11 * ) rt ) ;
}
Recycle ( rt ) ;
}
return dst ;
}
2015-05-15 18:45:31 +00:00
void GSDevice11 : : CopyRect ( GSTexture * sTex , GSTexture * dTex , const GSVector4i & r )
2010-01-28 13:07:06 +00:00
{
2015-05-15 18:45:31 +00:00
if ( ! sTex | | ! dTex )
2011-09-01 13:25:08 +00:00
{
ASSERT ( 0 ) ;
return ;
}
2010-01-28 13:07:06 +00:00
D3D11_BOX box = { r . left , r . top , 0 , r . right , r . bottom , 1 } ;
2015-05-15 18:45:31 +00:00
m_ctx - > CopySubresourceRegion ( * ( GSTexture11 * ) dTex , 0 , 0 , 0 , 0 , * ( GSTexture11 * ) sTex , 0 , & box ) ;
2010-01-28 13:07:06 +00:00
}
2015-05-15 18:49:25 +00:00
void GSDevice11 : : StretchRect ( GSTexture * sTex , const GSVector4 & sRect , GSTexture * dTex , const GSVector4 & dRect , int shader , bool linear )
2010-01-28 13:07:06 +00:00
{
2015-05-15 18:49:25 +00:00
StretchRect ( sTex , sRect , dTex , dRect , m_convert . ps [ shader ] , NULL , linear ) ;
2010-01-28 13:07:06 +00:00
}
2015-05-15 18:49:25 +00:00
void GSDevice11 : : StretchRect ( GSTexture * sTex , const GSVector4 & sRect , GSTexture * dTex , const GSVector4 & dRect , ID3D11PixelShader * ps , ID3D11Buffer * ps_cb , bool linear )
2010-01-28 13:07:06 +00:00
{
2015-05-15 18:49:25 +00:00
StretchRect ( sTex , sRect , dTex , dRect , ps , ps_cb , m_convert . bs , linear ) ;
2010-01-28 13:07:06 +00:00
}
2015-05-15 18:49:25 +00:00
void GSDevice11 : : StretchRect ( GSTexture * sTex , const GSVector4 & sRect , GSTexture * dTex , const GSVector4 & dRect , ID3D11PixelShader * ps , ID3D11Buffer * ps_cb , ID3D11BlendState * bs , bool linear )
2010-01-28 13:07:06 +00:00
{
2015-05-15 18:45:31 +00:00
if ( ! sTex | | ! dTex )
2011-09-01 13:25:08 +00:00
{
ASSERT ( 0 ) ;
return ;
}
2010-01-28 13:07:06 +00:00
BeginScene ( ) ;
2015-05-15 18:43:57 +00:00
GSVector2i ds = dTex - > GetSize ( ) ;
2010-01-28 13:07:06 +00:00
// om
OMSetDepthStencilState ( m_convert . dss , 0 ) ;
OMSetBlendState ( bs , 0 ) ;
2015-05-15 18:43:57 +00:00
OMSetRenderTargets ( dTex , NULL ) ;
2010-01-28 13:07:06 +00:00
// ia
2015-05-15 18:49:25 +00:00
float left = dRect . x * 2 / ds . x - 1.0f ;
float top = 1.0f - dRect . y * 2 / ds . y ;
float right = dRect . z * 2 / ds . x - 1.0f ;
float bottom = 1.0f - dRect . w * 2 / ds . y ;
2010-01-28 13:07:06 +00:00
GSVertexPT1 vertices [ ] =
{
2015-05-15 18:47:14 +00:00
{ GSVector4 ( left , top , 0.5f , 1.0f ) , GSVector2 ( sRect . x , sRect . y ) } ,
{ GSVector4 ( right , top , 0.5f , 1.0f ) , GSVector2 ( sRect . z , sRect . y ) } ,
{ GSVector4 ( left , bottom , 0.5f , 1.0f ) , GSVector2 ( sRect . x , sRect . w ) } ,
{ GSVector4 ( right , bottom , 0.5f , 1.0f ) , GSVector2 ( sRect . z , sRect . w ) } ,
2010-01-28 13:07:06 +00:00
} ;
2015-05-28 20:41:02 +00:00
2010-01-28 13:07:06 +00:00
IASetVertexBuffer ( vertices , sizeof ( vertices [ 0 ] ) , countof ( vertices ) ) ;
IASetInputLayout ( m_convert . il ) ;
IASetPrimitiveTopology ( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP ) ;
// vs
VSSetShader ( m_convert . vs , NULL ) ;
2015-05-28 20:41:02 +00:00
2010-01-28 13:07:06 +00:00
// gs
2015-05-28 20:41:02 +00:00
/* NVIDIA HACK!!!!
Not sure why , but having the Geometry shader disabled causes the strange stretching in recent drivers */
GSSelector sel ;
2015-08-19 22:01:39 +00:00
//Don't use shading for stretching, we're just passing through - Note: With Win10 it seems to cause other bugs when shading is off if any of the coords is greater than 0
//I really don't know whats going on there, but this seems to resolve it mostly (if not all, not tester a lot of games, only BIOS, FFXII and VP2)
2015-08-20 22:45:00 +00:00
//sel.iip = (sRect.y > 0.0f || sRect.w > 0.0f) ? 1 : 0;
//sel.prim = 2; //Triangle Strip
//SetupGS(sel);
2010-01-28 13:07:06 +00:00
2015-08-20 22:45:00 +00:00
GSSetShader ( NULL ) ;
2015-05-28 20:41:02 +00:00
/*END OF HACK*/
//
2010-01-28 13:07:06 +00:00
// ps
2015-05-15 18:45:31 +00:00
PSSetShaderResources ( sTex , NULL ) ;
2010-05-14 14:05:39 +00:00
PSSetSamplerState ( linear ? m_convert . ln : m_convert . pt , NULL ) ;
PSSetShader ( ps , ps_cb ) ;
2010-01-28 13:07:06 +00:00
//
DrawPrimitive ( ) ;
//
EndScene ( ) ;
PSSetShaderResources ( NULL , NULL ) ;
}
2015-05-15 18:49:25 +00:00
void GSDevice11 : : DoMerge ( GSTexture * sTex [ 2 ] , GSVector4 * sRect , GSTexture * dTex , GSVector4 * dRect , bool slbg , bool mmod , const GSVector4 & c )
2010-01-28 13:07:06 +00:00
{
2015-05-15 18:43:57 +00:00
ClearRenderTarget ( dTex , c ) ;
2010-01-28 13:07:06 +00:00
2015-05-15 18:45:31 +00:00
if ( sTex [ 1 ] & & ! slbg )
2010-01-28 13:07:06 +00:00
{
2015-05-15 18:49:25 +00:00
StretchRect ( sTex [ 1 ] , sRect [ 1 ] , dTex , dRect [ 1 ] , m_merge . ps [ 0 ] , NULL , true ) ;
2010-01-28 13:07:06 +00:00
}
2015-05-15 18:45:31 +00:00
if ( sTex [ 0 ] )
2010-01-28 13:07:06 +00:00
{
m_ctx - > UpdateSubresource ( m_merge . cb , 0 , NULL , & c , 0 , 0 ) ;
2015-05-15 18:49:25 +00:00
StretchRect ( sTex [ 0 ] , sRect [ 0 ] , dTex , dRect [ 0 ] , m_merge . ps [ mmod ? 1 : 0 ] , m_merge . cb , m_merge . bs , true ) ;
2010-01-28 13:07:06 +00:00
}
}
2015-05-15 18:45:31 +00:00
void GSDevice11 : : DoInterlace ( GSTexture * sTex , GSTexture * dTex , int shader , bool linear , float yoffset )
2010-01-28 13:07:06 +00:00
{
2015-05-15 18:43:57 +00:00
GSVector4 s = GSVector4 ( dTex - > GetSize ( ) ) ;
2010-01-28 13:07:06 +00:00
2015-05-15 18:47:14 +00:00
GSVector4 sRect ( 0 , 0 , 1 , 1 ) ;
2015-05-15 18:49:25 +00:00
GSVector4 dRect ( 0.0f , yoffset , s . x , s . y + yoffset ) ;
2010-01-28 13:07:06 +00:00
InterlaceConstantBuffer cb ;
cb . ZrH = GSVector2 ( 0 , 1.0f / s . y ) ;
cb . hH = s . y / 2 ;
m_ctx - > UpdateSubresource ( m_interlace . cb , 0 , NULL , & cb , 0 , 0 ) ;
2015-05-15 18:49:25 +00:00
StretchRect ( sTex , sRect , dTex , dRect , m_interlace . ps [ shader ] , m_interlace . cb , linear ) ;
2010-01-28 13:07:06 +00:00
}
2014-01-17 10:17:24 +00:00
//Included an init function for this also. Just to be safe.
void GSDevice11 : : InitExternalFX ( )
{
if ( ! ExShader_Compiled )
{
try {
2015-08-29 16:50:10 +00:00
std : : string config_name ( theApp . GetConfig ( " shaderfx_conf " , " shaders/GSdx_FX_Settings.ini " ) ) ;
std : : ifstream fconfig ( config_name ) ;
std : : stringstream shader ;
if ( fconfig . good ( ) )
shader < < fconfig . rdbuf ( ) < < " \n " ;
else
fprintf ( stderr , " GSdx: External shader config '%s' not loaded. \n " , config_name . c_str ( ) ) ;
std : : string shader_name ( theApp . GetConfig ( " shaderfx_glsl " , " shaders/GSdx.fx " ) ) ;
std : : ifstream fshader ( shader_name ) ;
2015-08-29 15:53:29 +00:00
if ( fshader . good ( ) )
{
shader < < fshader . rdbuf ( ) ;
2015-08-29 16:50:10 +00:00
CompileShader ( shader . str ( ) . c_str ( ) , shader . str ( ) . length ( ) , shader_name . c_str ( ) , " ps_main " , NULL , & m_shaderfx . ps ) ;
2015-08-29 15:53:29 +00:00
}
else
{
2015-08-29 16:50:10 +00:00
fprintf ( stderr , " GSdx: External shader '%s' not loaded and will be disabled! \n " , shader_name . c_str ( ) ) ;
2015-08-29 15:53:29 +00:00
}
2014-01-17 10:17:24 +00:00
}
catch ( GSDXRecoverableError ) {
2014-02-09 01:01:41 +00:00
printf ( " GSdx: failed to compile external post-processing shader. \n " ) ;
2014-01-17 10:17:24 +00:00
}
ExShader_Compiled = true ;
}
}
2015-05-15 18:45:31 +00:00
void GSDevice11 : : DoExternalFX ( GSTexture * sTex , GSTexture * dTex )
2014-01-17 10:17:24 +00:00
{
2015-05-15 18:43:57 +00:00
GSVector2i s = dTex - > GetSize ( ) ;
2014-01-17 10:17:24 +00:00
2015-05-15 18:47:14 +00:00
GSVector4 sRect ( 0 , 0 , 1 , 1 ) ;
2015-05-15 18:49:25 +00:00
GSVector4 dRect ( 0 , 0 , s . x , s . y ) ;
2014-01-17 10:17:24 +00:00
ExternalFXConstantBuffer cb ;
InitExternalFX ( ) ;
2014-11-03 07:15:34 +00:00
cb . xyFrame = GSVector2 ( s . x , s . y ) ;
2014-01-17 10:17:24 +00:00
cb . rcpFrame = GSVector4 ( 1.0f / s . x , 1.0f / s . y , 0.0f , 0.0f ) ;
cb . rcpFrameOpt = GSVector4 : : zero ( ) ;
m_ctx - > UpdateSubresource ( m_shaderfx . cb , 0 , NULL , & cb , 0 , 0 ) ;
2015-05-15 18:49:25 +00:00
StretchRect ( sTex , sRect , dTex , dRect , m_shaderfx . ps , m_shaderfx . cb , true ) ;
2014-01-17 10:17:24 +00:00
}
2014-01-09 21:51:42 +00:00
// This shouldn't be necessary, we have some bug corrupting memory
// and for some reason isolating this code makes the plugin not crash
void GSDevice11 : : InitFXAA ( )
2011-07-25 11:16:01 +00:00
{
2014-02-02 17:50:32 +00:00
if ( ! FXAA_Compiled )
2014-01-07 23:53:30 +00:00
{
2014-01-17 10:17:24 +00:00
try {
2015-08-29 15:53:29 +00:00
vector < unsigned char > shader ;
theApp . LoadResource ( IDR_FXAA_FX , shader ) ;
CompileShader ( ( const char * ) shader . data ( ) , shader . size ( ) , " fxaa.fx " , " ps_main " , NULL , & m_fxaa . ps ) ;
2014-01-17 10:17:24 +00:00
}
catch ( GSDXRecoverableError ) {
2014-02-09 01:01:41 +00:00
printf ( " GSdx: failed to compile fxaa shader. \n " ) ;
2014-01-17 10:17:24 +00:00
}
2014-02-02 17:50:32 +00:00
FXAA_Compiled = true ;
2014-01-07 23:53:30 +00:00
}
2014-01-09 21:51:42 +00:00
}
2015-05-15 18:45:31 +00:00
void GSDevice11 : : DoFXAA ( GSTexture * sTex , GSTexture * dTex )
2014-01-09 21:51:42 +00:00
{
2015-05-15 18:43:57 +00:00
GSVector2i s = dTex - > GetSize ( ) ;
2014-01-09 21:51:42 +00:00
2015-05-15 18:47:14 +00:00
GSVector4 sRect ( 0 , 0 , 1 , 1 ) ;
2015-05-15 18:49:25 +00:00
GSVector4 dRect ( 0 , 0 , s . x , s . y ) ;
2014-01-09 21:51:42 +00:00
FXAAConstantBuffer cb ;
InitFXAA ( ) ;
2014-01-17 10:17:24 +00:00
2011-07-25 11:16:01 +00:00
cb . rcpFrame = GSVector4 ( 1.0f / s . x , 1.0f / s . y , 0.0f , 0.0f ) ;
cb . rcpFrameOpt = GSVector4 : : zero ( ) ;
m_ctx - > UpdateSubresource ( m_fxaa . cb , 0 , NULL , & cb , 0 , 0 ) ;
2015-05-15 18:49:25 +00:00
StretchRect ( sTex , sRect , dTex , dRect , m_fxaa . ps , m_fxaa . cb , true ) ;
2011-07-25 11:16:01 +00:00
2015-05-15 18:45:31 +00:00
//sTex->Save("c:\\temp1\\1.bmp");
2015-05-15 18:43:57 +00:00
//dTex->Save("c:\\temp1\\2.bmp");
2011-07-25 11:16:01 +00:00
}
2015-05-15 18:45:31 +00:00
void GSDevice11 : : DoShadeBoost ( GSTexture * sTex , GSTexture * dTex )
2012-02-29 00:29:29 +00:00
{
2015-05-15 18:43:57 +00:00
GSVector2i s = dTex - > GetSize ( ) ;
2012-02-29 00:29:29 +00:00
2015-05-15 18:47:14 +00:00
GSVector4 sRect ( 0 , 0 , 1 , 1 ) ;
2015-05-15 18:49:25 +00:00
GSVector4 dRect ( 0 , 0 , s . x , s . y ) ;
2012-02-29 00:29:29 +00:00
ShadeBoostConstantBuffer cb ;
cb . rcpFrame = GSVector4 ( 1.0f / s . x , 1.0f / s . y , 0.0f , 0.0f ) ;
cb . rcpFrameOpt = GSVector4 : : zero ( ) ;
m_ctx - > UpdateSubresource ( m_shadeboost . cb , 0 , NULL , & cb , 0 , 0 ) ;
2015-05-15 18:49:25 +00:00
StretchRect ( sTex , sRect , dTex , dRect , m_shadeboost . ps , m_shadeboost . cb , true ) ;
2012-02-29 00:29:29 +00:00
}
2011-02-18 03:50:12 +00:00
void GSDevice11 : : SetupDATE ( GSTexture * rt , GSTexture * ds , const GSVertexPT1 * vertices , bool datm )
2010-01-28 13:07:06 +00:00
{
2012-07-23 22:55:06 +00:00
// sfex3 (after the capcom logo), vf4 (first menu fading in), ffxii shadows, rumble roses shadows, persona4 shadows
2010-01-28 13:07:06 +00:00
2012-07-23 22:55:06 +00:00
BeginScene ( ) ;
2010-01-28 13:07:06 +00:00
2012-07-23 22:55:06 +00:00
ClearStencil ( ds , 0 ) ;
2010-01-28 13:07:06 +00:00
2012-07-23 22:55:06 +00:00
// om
2010-01-28 13:07:06 +00:00
2012-07-23 22:55:06 +00:00
OMSetDepthStencilState ( m_date . dss , 1 ) ;
OMSetBlendState ( m_date . bs , 0 ) ;
OMSetRenderTargets ( NULL , ds ) ;
2010-01-28 13:07:06 +00:00
2012-07-23 22:55:06 +00:00
// ia
2010-01-28 13:07:06 +00:00
2012-07-23 22:55:06 +00:00
IASetVertexBuffer ( vertices , sizeof ( vertices [ 0 ] ) , 4 ) ;
IASetInputLayout ( m_convert . il ) ;
IASetPrimitiveTopology ( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP ) ;
2010-01-28 13:07:06 +00:00
2012-07-23 22:55:06 +00:00
// vs
2010-01-28 13:07:06 +00:00
2012-07-23 22:55:06 +00:00
VSSetShader ( m_convert . vs , NULL ) ;
2010-01-28 13:07:06 +00:00
2012-07-23 22:55:06 +00:00
// gs
2010-01-28 13:07:06 +00:00
2012-07-23 22:55:06 +00:00
GSSetShader ( NULL ) ;
2010-01-28 13:07:06 +00:00
2012-07-23 22:55:06 +00:00
// ps
2010-01-28 13:07:06 +00:00
2012-07-23 22:55:06 +00:00
GSTexture * rt2 = rt - > IsMSAA ( ) ? Resolve ( rt ) : rt ;
2010-01-28 13:07:06 +00:00
2012-07-23 22:55:06 +00:00
PSSetShaderResources ( rt2 , NULL ) ;
PSSetSamplerState ( m_convert . pt , NULL ) ;
PSSetShader ( m_convert . ps [ datm ? 2 : 3 ] , NULL ) ;
2010-01-28 13:07:06 +00:00
2012-07-23 22:55:06 +00:00
//
2010-01-28 13:07:06 +00:00
2012-07-23 22:55:06 +00:00
DrawPrimitive ( ) ;
2010-01-28 13:07:06 +00:00
2012-07-23 22:55:06 +00:00
//
2010-01-28 13:07:06 +00:00
2012-07-23 22:55:06 +00:00
EndScene ( ) ;
2010-01-28 13:07:06 +00:00
2012-07-23 22:55:06 +00:00
if ( rt2 ! = rt ) Recycle ( rt2 ) ;
2010-01-28 13:07:06 +00:00
}
2012-01-05 02:40:24 +00:00
void GSDevice11 : : IASetVertexBuffer ( const void * vertex , size_t stride , size_t count )
2012-01-19 04:53:36 +00:00
{
void * ptr = NULL ;
if ( IAMapVertexBuffer ( & ptr , stride , count ) )
{
GSVector4i : : storent ( ptr , vertex , count * stride ) ;
IAUnmapVertexBuffer ( ) ;
}
}
bool GSDevice11 : : IAMapVertexBuffer ( void * * vertex , size_t stride , size_t count )
2010-01-28 13:07:06 +00:00
{
2012-01-05 02:40:24 +00:00
ASSERT ( m_vertex . count = = 0 ) ;
2010-01-28 13:07:06 +00:00
2012-01-05 02:40:24 +00:00
if ( count * stride > m_vertex . limit * m_vertex . stride )
2010-01-28 13:07:06 +00:00
{
m_vb_old = m_vb ;
m_vb = NULL ;
2012-01-05 02:40:24 +00:00
m_vertex . start = 0 ;
m_vertex . limit = std : : max < int > ( count * 3 / 2 , 11000 ) ;
2010-01-28 13:07:06 +00:00
}
if ( m_vb = = NULL )
{
D3D11_BUFFER_DESC bd ;
memset ( & bd , 0 , sizeof ( bd ) ) ;
bd . Usage = D3D11_USAGE_DYNAMIC ;
2012-01-05 02:40:24 +00:00
bd . ByteWidth = m_vertex . limit * stride ;
2010-01-28 13:07:06 +00:00
bd . BindFlags = D3D11_BIND_VERTEX_BUFFER ;
bd . CPUAccessFlags = D3D11_CPU_ACCESS_WRITE ;
HRESULT hr ;
2010-04-25 00:31:27 +00:00
2010-01-28 13:07:06 +00:00
hr = m_dev - > CreateBuffer ( & bd , NULL , & m_vb ) ;
2012-01-19 04:53:36 +00:00
if ( FAILED ( hr ) ) return false ;
2010-01-28 13:07:06 +00:00
}
D3D11_MAP type = D3D11_MAP_WRITE_NO_OVERWRITE ;
2012-01-05 02:40:24 +00:00
if ( m_vertex . start + count > m_vertex . limit | | stride ! = m_vertex . stride )
2010-01-28 13:07:06 +00:00
{
2012-01-05 02:40:24 +00:00
m_vertex . start = 0 ;
2010-01-28 13:07:06 +00:00
type = D3D11_MAP_WRITE_DISCARD ;
}
D3D11_MAPPED_SUBRESOURCE m ;
2012-01-19 04:53:36 +00:00
if ( FAILED ( m_ctx - > Map ( m_vb , 0 , type , 0 , & m ) ) )
2010-01-28 13:07:06 +00:00
{
2012-01-19 04:53:36 +00:00
return false ;
2010-01-28 13:07:06 +00:00
}
2012-01-19 04:53:36 +00:00
* vertex = ( uint8 * ) m . pData + m_vertex . start * stride ;
2012-01-05 02:40:24 +00:00
m_vertex . count = count ;
m_vertex . stride = stride ;
2010-01-28 13:07:06 +00:00
2012-01-19 04:53:36 +00:00
return true ;
}
void GSDevice11 : : IAUnmapVertexBuffer ( )
{
m_ctx - > Unmap ( m_vb , 0 ) ;
IASetVertexBuffer ( m_vb , m_vertex . stride ) ;
2010-01-28 13:07:06 +00:00
}
void GSDevice11 : : IASetVertexBuffer ( ID3D11Buffer * vb , size_t stride )
{
if ( m_state . vb ! = vb | | m_state . vb_stride ! = stride )
{
m_state . vb = vb ;
m_state . vb_stride = stride ;
2011-02-12 21:45:16 +00:00
uint32 stride2 = stride ;
2010-01-28 13:07:06 +00:00
uint32 offset = 0 ;
2011-02-12 21:45:16 +00:00
m_ctx - > IASetVertexBuffers ( 0 , 1 , & vb , & stride2 , & offset ) ;
2010-01-28 13:07:06 +00:00
}
}
2012-01-05 02:40:24 +00:00
void GSDevice11 : : IASetIndexBuffer ( const void * index , size_t count )
{
ASSERT ( m_index . count = = 0 ) ;
if ( count > m_index . limit )
{
m_ib_old = m_ib ;
m_ib = NULL ;
2012-01-18 11:47:31 +00:00
m_index . start = 0 ;
2012-01-05 02:40:24 +00:00
m_index . limit = std : : max < int > ( count * 3 / 2 , 11000 ) ;
}
if ( m_ib = = NULL )
{
D3D11_BUFFER_DESC bd ;
memset ( & bd , 0 , sizeof ( bd ) ) ;
bd . Usage = D3D11_USAGE_DYNAMIC ;
bd . ByteWidth = m_index . limit * sizeof ( uint32 ) ;
bd . BindFlags = D3D11_BIND_INDEX_BUFFER ;
bd . CPUAccessFlags = D3D11_CPU_ACCESS_WRITE ;
HRESULT hr ;
hr = m_dev - > CreateBuffer ( & bd , NULL , & m_ib ) ;
if ( FAILED ( hr ) ) return ;
}
D3D11_MAP type = D3D11_MAP_WRITE_NO_OVERWRITE ;
if ( m_index . start + count > m_index . limit )
{
m_index . start = 0 ;
type = D3D11_MAP_WRITE_DISCARD ;
}
D3D11_MAPPED_SUBRESOURCE m ;
if ( SUCCEEDED ( m_ctx - > Map ( m_ib , 0 , type , 0 , & m ) ) )
{
memcpy ( ( uint8 * ) m . pData + m_index . start * sizeof ( uint32 ) , index , count * sizeof ( uint32 ) ) ;
m_ctx - > Unmap ( m_ib , 0 ) ;
}
m_index . count = count ;
IASetIndexBuffer ( m_ib ) ;
}
void GSDevice11 : : IASetIndexBuffer ( ID3D11Buffer * ib )
{
if ( m_state . ib ! = ib )
{
m_state . ib = ib ;
m_ctx - > IASetIndexBuffer ( ib , DXGI_FORMAT_R32_UINT , 0 ) ;
}
}
2010-01-28 13:07:06 +00:00
void GSDevice11 : : IASetInputLayout ( ID3D11InputLayout * layout )
{
if ( m_state . layout ! = layout )
{
m_state . layout = layout ;
m_ctx - > IASetInputLayout ( layout ) ;
}
}
void GSDevice11 : : IASetPrimitiveTopology ( D3D11_PRIMITIVE_TOPOLOGY topology )
{
if ( m_state . topology ! = topology )
{
m_state . topology = topology ;
m_ctx - > IASetPrimitiveTopology ( topology ) ;
}
}
void GSDevice11 : : VSSetShader ( ID3D11VertexShader * vs , ID3D11Buffer * vs_cb )
{
if ( m_state . vs ! = vs )
{
m_state . vs = vs ;
m_ctx - > VSSetShader ( vs , NULL , 0 ) ;
}
2010-04-25 00:31:27 +00:00
2010-01-28 13:07:06 +00:00
if ( m_state . vs_cb ! = vs_cb )
{
m_state . vs_cb = vs_cb ;
m_ctx - > VSSetConstantBuffers ( 0 , 1 , & vs_cb ) ;
}
}
void GSDevice11 : : GSSetShader ( ID3D11GeometryShader * gs )
{
if ( m_state . gs ! = gs )
{
m_state . gs = gs ;
m_ctx - > GSSetShader ( gs , NULL , 0 ) ;
}
}
void GSDevice11 : : PSSetShaderResources ( GSTexture * sr0 , GSTexture * sr1 )
{
2010-05-14 14:05:39 +00:00
PSSetShaderResource ( 0 , sr0 ) ;
PSSetShaderResource ( 1 , sr1 ) ;
2012-01-18 11:47:31 +00:00
2013-06-29 12:02:03 +00:00
for ( size_t i = 2 ; i < countof ( m_state . ps_srv ) ; i + + )
2012-01-18 11:47:31 +00:00
{
PSSetShaderResource ( i , NULL ) ;
}
2010-05-14 14:05:39 +00:00
}
2015-05-21 07:48:15 +00:00
void GSDevice11 : : PSSetShaderResource ( int i , GSTexture * sr )
2010-05-14 14:05:39 +00:00
{
ID3D11ShaderResourceView * srv = NULL ;
2010-04-25 00:31:27 +00:00
2015-05-21 07:48:15 +00:00
if ( sr ) srv = * ( GSTexture11 * ) sr ;
2011-02-07 01:59:05 +00:00
2012-01-18 11:47:31 +00:00
PSSetShaderResourceView ( i , srv ) ;
}
void GSDevice11 : : PSSetShaderResourceView ( int i , ID3D11ShaderResourceView * srv )
{
ASSERT ( i < countof ( m_state . ps_srv ) ) ;
2011-02-22 23:39:02 +00:00
if ( m_state . ps_srv [ i ] ! = srv )
2011-02-07 01:59:05 +00:00
{
2010-05-14 14:05:39 +00:00
m_state . ps_srv [ i ] = srv ;
2011-02-07 01:59:05 +00:00
2010-05-14 14:05:39 +00:00
m_srv_changed = true ;
}
}
2010-01-28 13:07:06 +00:00
2010-05-14 14:05:39 +00:00
void GSDevice11 : : PSSetSamplerState ( ID3D11SamplerState * ss0 , ID3D11SamplerState * ss1 , ID3D11SamplerState * ss2 )
{
if ( m_state . ps_ss [ 0 ] ! = ss0 | | m_state . ps_ss [ 1 ] ! = ss1 | | m_state . ps_ss [ 2 ] ! = ss2 )
2010-01-28 13:07:06 +00:00
{
2010-05-14 14:05:39 +00:00
m_state . ps_ss [ 0 ] = ss0 ;
m_state . ps_ss [ 1 ] = ss1 ;
m_state . ps_ss [ 2 ] = ss2 ;
2010-04-25 00:31:27 +00:00
2010-05-14 14:05:39 +00:00
m_ss_changed = true ;
2010-01-28 13:07:06 +00:00
}
}
void GSDevice11 : : PSSetShader ( ID3D11PixelShader * ps , ID3D11Buffer * ps_cb )
{
if ( m_state . ps ! = ps )
{
m_state . ps = ps ;
m_ctx - > PSSetShader ( ps , NULL , 0 ) ;
}
2010-04-25 00:31:27 +00:00
2012-01-13 18:10:05 +00:00
if ( m_srv_changed )
2011-02-07 01:59:05 +00:00
{
2012-01-18 11:47:31 +00:00
m_ctx - > PSSetShaderResources ( 0 , countof ( m_state . ps_srv ) , m_state . ps_srv ) ;
2011-02-22 23:39:02 +00:00
2010-05-14 14:05:39 +00:00
m_srv_changed = false ;
}
2010-01-28 13:07:06 +00:00
2011-02-22 23:39:02 +00:00
if ( m_ss_changed )
2011-02-07 01:59:05 +00:00
{
2012-01-18 11:47:31 +00:00
m_ctx - > PSSetSamplers ( 0 , countof ( m_state . ps_ss ) , m_state . ps_ss ) ;
2011-02-22 23:39:02 +00:00
2010-05-14 14:05:39 +00:00
m_ss_changed = false ;
2010-01-28 13:07:06 +00:00
}
2010-05-14 14:05:39 +00:00
if ( m_state . ps_cb ! = ps_cb )
2010-01-28 13:07:06 +00:00
{
2010-05-14 14:05:39 +00:00
m_state . ps_cb = ps_cb ;
2010-01-28 13:07:06 +00:00
2010-05-14 14:05:39 +00:00
m_ctx - > PSSetConstantBuffers ( 0 , 1 , & ps_cb ) ;
2010-01-28 13:07:06 +00:00
}
}
2012-01-13 18:10:05 +00:00
void GSDevice11 : : CSSetShaderSRV ( int i , ID3D11ShaderResourceView * srv )
{
2012-01-27 11:56:49 +00:00
if ( m_state . cs_srv [ i ] ! = srv )
2012-01-13 18:10:05 +00:00
{
2012-01-27 11:56:49 +00:00
m_state . cs_srv [ i ] = srv ;
2012-01-13 18:10:05 +00:00
m_ctx - > CSSetShaderResources ( i , 1 , & srv ) ;
}
}
void GSDevice11 : : CSSetShaderUAV ( int i , ID3D11UnorderedAccessView * uav )
{
2012-01-27 11:56:49 +00:00
uint32 counters [ 8 ] ;
memset ( counters , 0 , sizeof ( counters ) ) ;
2012-01-13 18:10:05 +00:00
2012-01-27 11:56:49 +00:00
m_ctx - > CSSetUnorderedAccessViews ( i , 1 , & uav , counters ) ;
2012-01-13 18:10:05 +00:00
}
2012-01-27 11:56:49 +00:00
void GSDevice11 : : CSSetShader ( ID3D11ComputeShader * cs , ID3D11Buffer * cs_cb )
2012-01-13 18:10:05 +00:00
{
if ( m_state . cs ! = cs )
{
m_state . cs = cs ;
m_ctx - > CSSetShader ( cs , NULL , 0 ) ;
}
2012-01-27 11:56:49 +00:00
if ( m_state . cs_cb ! = cs_cb )
{
m_state . cs_cb = cs_cb ;
m_ctx - > CSSetConstantBuffers ( 0 , 1 , & cs_cb ) ;
}
2012-01-13 18:10:05 +00:00
}
2010-01-28 13:07:06 +00:00
void GSDevice11 : : OMSetDepthStencilState ( ID3D11DepthStencilState * dss , uint8 sref )
{
if ( m_state . dss ! = dss | | m_state . sref ! = sref )
{
m_state . dss = dss ;
m_state . sref = sref ;
m_ctx - > OMSetDepthStencilState ( dss , sref ) ;
}
}
void GSDevice11 : : OMSetBlendState ( ID3D11BlendState * bs , float bf )
{
if ( m_state . bs ! = bs | | m_state . bf ! = bf )
{
m_state . bs = bs ;
m_state . bf = bf ;
float BlendFactor [ ] = { bf , bf , bf , 0 } ;
m_ctx - > OMSetBlendState ( bs , BlendFactor , 0xffffffff ) ;
}
}
void GSDevice11 : : OMSetRenderTargets ( GSTexture * rt , GSTexture * ds , const GSVector4i * scissor )
{
ID3D11RenderTargetView * rtv = NULL ;
ID3D11DepthStencilView * dsv = NULL ;
2012-07-23 22:55:06 +00:00
if ( ! rt & & ! ds )
throw GSDXRecoverableError ( ) ;
2010-01-28 13:07:06 +00:00
if ( rt ) rtv = * ( GSTexture11 * ) rt ;
if ( ds ) dsv = * ( GSTexture11 * ) ds ;
if ( m_state . rtv ! = rtv | | m_state . dsv ! = dsv )
{
m_state . rtv = rtv ;
m_state . dsv = dsv ;
m_ctx - > OMSetRenderTargets ( 1 , & rtv , dsv ) ;
}
2012-07-23 22:55:06 +00:00
GSVector2i size = rt ? rt - > GetSize ( ) : ds - > GetSize ( ) ;
if ( m_state . viewport ! = size )
2010-01-28 13:07:06 +00:00
{
2012-07-23 22:55:06 +00:00
m_state . viewport = size ;
2010-01-28 13:07:06 +00:00
D3D11_VIEWPORT vp ;
memset ( & vp , 0 , sizeof ( vp ) ) ;
2010-04-25 00:31:27 +00:00
2015-11-10 22:58:43 +00:00
vp . TopLeftX = ( spritehack > 0 ) ? 0.0f : - 0.01f ;
vp . TopLeftY = ( spritehack > 0 ) ? 0.0f : - 0.01f ;
2012-07-23 22:55:06 +00:00
vp . Width = ( float ) size . x ;
vp . Height = ( float ) size . y ;
2010-01-28 13:07:06 +00:00
vp . MinDepth = 0.0f ;
vp . MaxDepth = 1.0f ;
m_ctx - > RSSetViewports ( 1 , & vp ) ;
}
2012-07-23 22:55:06 +00:00
GSVector4i r = scissor ? * scissor : GSVector4i ( size ) . zwxy ( ) ;
2010-01-28 13:07:06 +00:00
if ( ! m_state . scissor . eq ( r ) )
{
m_state . scissor = r ;
m_ctx - > RSSetScissorRects ( 1 , r ) ;
}
}
2012-01-27 11:56:49 +00:00
void GSDevice11 : : OMSetRenderTargets ( const GSVector2i & rtsize , int count , ID3D11UnorderedAccessView * * uav , uint32 * counters , const GSVector4i * scissor )
2012-01-18 11:47:31 +00:00
{
2012-01-27 11:56:49 +00:00
m_ctx - > OMSetRenderTargetsAndUnorderedAccessViews ( 0 , NULL , NULL , 0 , count , uav , counters ) ;
2012-01-18 11:47:31 +00:00
m_state . rtv = NULL ;
m_state . dsv = NULL ;
if ( m_state . viewport ! = rtsize )
{
m_state . viewport = rtsize ;
D3D11_VIEWPORT vp ;
memset ( & vp , 0 , sizeof ( vp ) ) ;
vp . TopLeftX = 0 ;
vp . TopLeftY = 0 ;
vp . Width = ( float ) rtsize . x ;
vp . Height = ( float ) rtsize . y ;
vp . MinDepth = 0.0f ;
vp . MaxDepth = 1.0f ;
m_ctx - > RSSetViewports ( 1 , & vp ) ;
}
GSVector4i r = scissor ? * scissor : GSVector4i ( rtsize ) . zwxy ( ) ;
if ( ! m_state . scissor . eq ( r ) )
{
m_state . scissor = r ;
m_ctx - > RSSetScissorRects ( 1 , r ) ;
}
}
2015-08-29 15:53:29 +00:00
void GSDevice11 : : CompileShader ( const char * source , size_t size , const char * fn , const char * entry , D3D11_SHADER_MACRO * macro , ID3D11VertexShader * * vs , D3D11_INPUT_ELEMENT_DESC * layout , int count , ID3D11InputLayout * * il )
2010-01-28 13:07:06 +00:00
{
HRESULT hr ;
vector < D3D11_SHADER_MACRO > m ;
PrepareShaderMacro ( m , macro ) ;
CComPtr < ID3D11Blob > shader , error ;
2015-08-29 15:53:29 +00:00
hr = D3DX11CompileFromMemory ( source , size , fn , & m [ 0 ] , NULL , entry , m_shader . vs . c_str ( ) , 0 , 0 , NULL , & shader , & error , NULL ) ;
2010-04-25 00:31:27 +00:00
2010-01-28 13:07:06 +00:00
if ( error )
{
printf ( " %s \n " , ( const char * ) error - > GetBufferPointer ( ) ) ;
}
if ( FAILED ( hr ) )
{
2012-06-11 02:31:44 +00:00
throw GSDXRecoverableError ( ) ;
2010-01-28 13:07:06 +00:00
}
hr = m_dev - > CreateVertexShader ( ( void * ) shader - > GetBufferPointer ( ) , shader - > GetBufferSize ( ) , NULL , vs ) ;
if ( FAILED ( hr ) )
{
2012-06-11 02:31:44 +00:00
throw GSDXRecoverableError ( ) ;
2010-01-28 13:07:06 +00:00
}
hr = m_dev - > CreateInputLayout ( layout , count , shader - > GetBufferPointer ( ) , shader - > GetBufferSize ( ) , il ) ;
if ( FAILED ( hr ) )
{
2012-06-11 02:31:44 +00:00
throw GSDXRecoverableError ( ) ;
2010-01-28 13:07:06 +00:00
}
}
2015-08-29 15:53:29 +00:00
void GSDevice11 : : CompileShader ( const char * source , size_t size , const char * fn , const char * entry , D3D11_SHADER_MACRO * macro , ID3D11GeometryShader * * gs )
2010-01-28 13:07:06 +00:00
{
HRESULT hr ;
vector < D3D11_SHADER_MACRO > m ;
PrepareShaderMacro ( m , macro ) ;
CComPtr < ID3D11Blob > shader , error ;
2015-08-29 15:53:29 +00:00
hr = D3DX11CompileFromMemory ( source , size , fn , & m [ 0 ] , NULL , entry , m_shader . gs . c_str ( ) , 0 , 0 , NULL , & shader , & error , NULL ) ;
2010-04-25 00:31:27 +00:00
2010-01-28 13:07:06 +00:00
if ( error )
{
printf ( " %s \n " , ( const char * ) error - > GetBufferPointer ( ) ) ;
}
if ( FAILED ( hr ) )
{
2012-06-11 02:31:44 +00:00
throw GSDXRecoverableError ( ) ;
2010-01-28 13:07:06 +00:00
}
hr = m_dev - > CreateGeometryShader ( ( void * ) shader - > GetBufferPointer ( ) , shader - > GetBufferSize ( ) , NULL , gs ) ;
if ( FAILED ( hr ) )
{
2012-06-11 02:31:44 +00:00
throw GSDXRecoverableError ( ) ;
2010-01-28 13:07:06 +00:00
}
}
2015-08-29 15:53:29 +00:00
void GSDevice11 : : CompileShader ( const char * source , size_t size , const char * fn , const char * entry , D3D11_SHADER_MACRO * macro , ID3D11GeometryShader * * gs , D3D11_SO_DECLARATION_ENTRY * layout , int count )
2012-01-18 11:47:31 +00:00
{
HRESULT hr ;
vector < D3D11_SHADER_MACRO > m ;
PrepareShaderMacro ( m , macro ) ;
CComPtr < ID3D11Blob > shader , error ;
2015-08-29 15:53:29 +00:00
hr = D3DX11CompileFromMemory ( source , size , fn , & m [ 0 ] , NULL , entry , m_shader . gs . c_str ( ) , 0 , 0 , NULL , & shader , & error , NULL ) ;
2012-01-18 11:47:31 +00:00
if ( error )
{
printf ( " %s \n " , ( const char * ) error - > GetBufferPointer ( ) ) ;
}
if ( FAILED ( hr ) )
{
2012-06-11 02:31:44 +00:00
throw GSDXRecoverableError ( ) ;
2012-01-18 11:47:31 +00:00
}
hr = m_dev - > CreateGeometryShaderWithStreamOutput ( ( void * ) shader - > GetBufferPointer ( ) , shader - > GetBufferSize ( ) , layout , count , NULL , 0 , D3D11_SO_NO_RASTERIZED_STREAM , NULL , gs ) ;
if ( FAILED ( hr ) )
{
2012-06-11 02:31:44 +00:00
throw GSDXRecoverableError ( ) ;
2012-01-18 11:47:31 +00:00
}
}
2015-08-29 15:53:29 +00:00
void GSDevice11 : : CompileShader ( const char * source , size_t size , const char * fn , const char * entry , D3D11_SHADER_MACRO * macro , ID3D11PixelShader * * ps )
2012-01-13 18:10:05 +00:00
{
HRESULT hr ;
vector < D3D11_SHADER_MACRO > m ;
PrepareShaderMacro ( m , macro ) ;
CComPtr < ID3D11Blob > shader , error ;
2015-08-29 15:53:29 +00:00
hr = D3DX11CompileFromMemory ( source , size , fn , & m [ 0 ] , NULL , entry , m_shader . ps . c_str ( ) , 0 , 0 , NULL , & shader , & error , NULL ) ;
2012-01-13 18:10:05 +00:00
if ( error )
{
printf ( " %s \n " , ( const char * ) error - > GetBufferPointer ( ) ) ;
}
if ( FAILED ( hr ) )
{
2012-06-11 02:31:44 +00:00
throw GSDXRecoverableError ( ) ;
2012-01-13 18:10:05 +00:00
}
2015-08-29 15:53:29 +00:00
hr = m_dev - > CreatePixelShader ( ( void * ) shader - > GetBufferPointer ( ) , shader - > GetBufferSize ( ) , NULL , ps ) ;
2012-01-13 18:10:05 +00:00
if ( FAILED ( hr ) )
{
2012-06-11 02:31:44 +00:00
throw GSDXRecoverableError ( ) ;
2012-01-13 18:10:05 +00:00
}
}
2015-08-29 15:53:29 +00:00
void GSDevice11 : : CompileShader ( const char * source , size_t size , const char * fn , const char * entry , D3D11_SHADER_MACRO * macro , ID3D11ComputeShader * * cs )
2010-01-28 13:07:06 +00:00
{
HRESULT hr ;
vector < D3D11_SHADER_MACRO > m ;
PrepareShaderMacro ( m , macro ) ;
2010-03-19 20:27:06 +00:00
CComPtr < ID3D11Blob > shader , error ;
2010-01-28 13:07:06 +00:00
2015-08-29 15:53:29 +00:00
hr = D3DX11CompileFromMemory ( source , size , fn , & m [ 0 ] , NULL , entry , m_shader . cs . c_str ( ) , 0 , 0 , NULL , & shader , & error , NULL ) ;
2011-02-22 23:39:02 +00:00
2010-01-28 13:07:06 +00:00
if ( error )
{
printf ( " %s \n " , ( const char * ) error - > GetBufferPointer ( ) ) ;
}
if ( FAILED ( hr ) )
{
2012-06-11 02:31:44 +00:00
throw GSDXRecoverableError ( ) ;
2010-01-28 13:07:06 +00:00
}
2015-08-29 15:53:29 +00:00
hr = m_dev - > CreateComputeShader ( ( void * ) shader - > GetBufferPointer ( ) , shader - > GetBufferSize ( ) , NULL , cs ) ;
2010-01-28 13:07:06 +00:00
if ( FAILED ( hr ) )
{
2012-06-11 02:31:44 +00:00
throw GSDXRecoverableError ( ) ;
2010-01-28 13:07:06 +00:00
}
}
2011-02-22 23:39:02 +00:00