00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "LampBasic.h"
00026 #include "Graphics/Enumeration/GraphicsDeviceComboInformation.h"
00027 #include "Graphics/Enumeration/GraphicsDeviceEnumeration.h"
00028 #include "Graphics/System/LampGraphics.h"
00029 #include "Graphics/Primitive/GraphicsBufferFormat.h"
00030
00031 namespace Lamp{
00032
00033
00034
00035 GraphicsDeviceComboInformation::GraphicsDeviceComboInformation(
00036 D3DFORMAT adapterFormat, D3DFORMAT backBufferFormat, bool isWindowed) :
00037 adapterFormat_(adapterFormat), backBufferFormat_(backBufferFormat),
00038 isWindowed_(isWindowed){
00039 }
00040
00041
00042 GraphicsDeviceComboInformation::~GraphicsDeviceComboInformation(){
00043 }
00044
00045
00046 bool GraphicsDeviceComboInformation::enumerate(
00047 GraphicsDeviceEnumeration* enumeration,
00048 GraphicsDeviceInformation* deviceInformation){
00049
00050 adapterOrdinal_ = deviceInformation->getAdapterOrdinal();
00051 deviceType_ = deviceInformation->getDeviceType();
00052
00053
00054 if(enumeration->getUsesDepthStencilBuffer()){
00055 u_int minimumDepthBits = enumeration->getMinimumDepthBits();
00056 u_int minimumStencilBits = enumeration->getMinimumStencilBits();
00057 buildDepthStencilFormats(minimumDepthBits, minimumStencilBits);
00058 if(getDepthStencilFormatCount() == 0){ return false; }
00059 }
00060
00061
00062 buildMultiSampleType();
00063 if(getMultiSampleTypeCount() == 0){ return false; }
00064
00065 buildMultiSampleConflict();
00066
00067
00068 buildVertexProcessingType(
00069 deviceInformation->getDeviceCapability(),
00070 enumeration->getUsesMixedVertexProcessing(),
00071 enumeration->getConfirmGraphicsDevice());
00072 if(getVertexProcessingTypeCount() == 0){ return false; }
00073
00074
00075 buildPresentationInterval(deviceInformation->getDeviceCapability());
00076 return true;
00077 }
00078
00079
00080 void GraphicsDeviceComboInformation::buildDepthStencilFormats(
00081 u_int minimumDepthBits, u_int minimumStencilBits){
00082 Direct3D* direct3D = LampGraphics::getDirect3D();
00083
00084 const D3DFORMAT depthStencilFormatArray[] = {
00085 D3DFMT_D16,
00086 D3DFMT_D15S1,
00087 D3DFMT_D24X8,
00088 D3DFMT_D24S8,
00089 D3DFMT_D24X4S4,
00090 D3DFMT_D32};
00091 const u_int depthStencilFormatArrayCount =
00092 sizeof(depthStencilFormatArray) / sizeof(depthStencilFormatArray[0]);
00093 for(u_int i = 0; i < depthStencilFormatArrayCount; i++){
00094 D3DFORMAT depthStencilFormat = depthStencilFormatArray[i];
00095 GraphicsBufferFormat bufferFormat(depthStencilFormat);
00096
00097 if(bufferFormat.getDepthBits() < minimumDepthBits){ continue; }
00098
00099 if(bufferFormat.getStencilBits() < minimumStencilBits){ continue; }
00100
00101 if(DirectXSucceeded(direct3D->CheckDeviceFormat(
00102 adapterOrdinal_, deviceType_, adapterFormat_,
00103 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, depthStencilFormat))){
00104
00105 if(DirectXSucceeded(direct3D->CheckDepthStencilMatch(
00106 adapterOrdinal_, deviceType_, adapterFormat_,
00107 backBufferFormat_, depthStencilFormat))){
00108 depthStencilFormats_.add(depthStencilFormat);
00109 }
00110 }
00111 }
00112 }
00113
00114
00115 void GraphicsDeviceComboInformation::buildMultiSampleType(){
00116 Direct3D* direct3D = LampGraphics::getDirect3D();
00117
00118 const D3DMULTISAMPLE_TYPE multiSampleTypeArray[] = {
00119 D3DMULTISAMPLE_NONE,
00120 D3DMULTISAMPLE_NONMASKABLE,
00121 D3DMULTISAMPLE_2_SAMPLES,
00122 D3DMULTISAMPLE_3_SAMPLES,
00123 D3DMULTISAMPLE_4_SAMPLES,
00124 D3DMULTISAMPLE_5_SAMPLES,
00125 D3DMULTISAMPLE_6_SAMPLES,
00126 D3DMULTISAMPLE_7_SAMPLES,
00127 D3DMULTISAMPLE_8_SAMPLES,
00128 D3DMULTISAMPLE_9_SAMPLES,
00129 D3DMULTISAMPLE_10_SAMPLES,
00130 D3DMULTISAMPLE_11_SAMPLES,
00131 D3DMULTISAMPLE_12_SAMPLES,
00132 D3DMULTISAMPLE_13_SAMPLES,
00133 D3DMULTISAMPLE_14_SAMPLES,
00134 D3DMULTISAMPLE_15_SAMPLES,
00135 D3DMULTISAMPLE_16_SAMPLES};
00136 const u_int multiSampleTypeArrayCount =
00137 sizeof(multiSampleTypeArray) / sizeof(multiSampleTypeArray[0]);
00138 for(int i = 0; i < multiSampleTypeArrayCount; i++){
00139 D3DMULTISAMPLE_TYPE multiSampleType = multiSampleTypeArray[i];
00140 unsigned long multiSampleQuality;
00141
00142 if(DirectXSucceeded(direct3D->CheckDeviceMultiSampleType(
00143 adapterOrdinal_, deviceType_, backBufferFormat_, isWindowed_,
00144 multiSampleType, &multiSampleQuality))){
00145 multiSampleTypes_.add(multiSampleType);
00146 multiSampleTypeQualities_.add((u_int)multiSampleQuality);
00147 }
00148 }
00149 }
00150
00151
00152 void GraphicsDeviceComboInformation::buildMultiSampleConflict(){
00153 Direct3D* direct3D = LampGraphics::getDirect3D();
00154
00155 u_int depthStencilFormatCount = getDepthStencilFormatCount();
00156 for(u_int i = 0; i < depthStencilFormatCount; i++){
00157 D3DFORMAT depthStencilFormat = getDepthStencilFormat(i);
00158
00159 u_int multiSampleTypeCount = getMultiSampleTypeCount();
00160 for(u_int j = 0; j < multiSampleTypeCount; j++){
00161 D3DMULTISAMPLE_TYPE multiSampleType = getMultiSampleType(j);
00162 if(DirectXFailed(direct3D->CheckDeviceMultiSampleType(
00163 adapterOrdinal_, deviceType_, depthStencilFormat, isWindowed_,
00164 multiSampleType, NULL))){
00165 multiSampleConflictFormats_.add(depthStencilFormat);
00166 multiSampleConflictTypes_.add(multiSampleType);
00167 }
00168 }
00169 }
00170 }
00171
00172
00173 void GraphicsDeviceComboInformation::buildVertexProcessingType(
00174 const D3DCapacity& deviceCapability, bool usesMixedVertexProcessing,
00175 ConfirmGraphicsDevice* confirmDevice){
00176
00177 if((deviceCapability.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) != 0){
00178
00179 if((deviceCapability.DevCaps & D3DDEVCAPS_PUREDEVICE) != 0){
00180 if(confirmDevice->confirmGraphicsDevice(
00181 deviceCapability,
00182 (D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE),
00183 adapterFormat_, backBufferFormat_)){
00184 vertexProcessingTypes_.add(VertexProcessingType::pureHardware);
00185 }
00186 }
00187
00188 if(confirmDevice->confirmGraphicsDevice(
00189 deviceCapability,
00190 D3DCREATE_HARDWARE_VERTEXPROCESSING,
00191 adapterFormat_, backBufferFormat_)){
00192 vertexProcessingTypes_.add(VertexProcessingType::hardware);
00193 }
00194
00195 if(usesMixedVertexProcessing &&
00196 confirmDevice->confirmGraphicsDevice(
00197 deviceCapability,
00198 D3DCREATE_MIXED_VERTEXPROCESSING,
00199 adapterFormat_, backBufferFormat_)){
00200 vertexProcessingTypes_.add(VertexProcessingType::mixed);
00201 }
00202 }
00203
00204 if(confirmDevice->confirmGraphicsDevice(
00205 deviceCapability,
00206 D3DCREATE_SOFTWARE_VERTEXPROCESSING,
00207 adapterFormat_, backBufferFormat_)){
00208 vertexProcessingTypes_.add(VertexProcessingType::software);
00209 }
00210
00211 }
00212
00213
00214 void GraphicsDeviceComboInformation::buildPresentationInterval(
00215 const D3DCapacity& deviceCapability){
00216 const u_int presentationIntervalArray[] = {
00217 D3DPRESENT_INTERVAL_DEFAULT,
00218 D3DPRESENT_INTERVAL_IMMEDIATE,
00219 D3DPRESENT_INTERVAL_ONE,
00220 D3DPRESENT_INTERVAL_TWO,
00221 D3DPRESENT_INTERVAL_THREE,
00222 D3DPRESENT_INTERVAL_FOUR,
00223 };
00224 const u_int presentationIntervalArrayCount =
00225 sizeof(presentationIntervalArray) / sizeof(presentationIntervalArray[0]);
00226 for(u_int i = 0; i < presentationIntervalArrayCount; i++){
00227 u_int presentationInterval = presentationIntervalArray[i];
00228
00229 if(isWindowed_){
00230 if((presentationInterval == D3DPRESENT_INTERVAL_TWO) ||
00231 (presentationInterval == D3DPRESENT_INTERVAL_THREE) ||
00232 (presentationInterval == D3DPRESENT_INTERVAL_FOUR)){
00233 continue;
00234 }
00235 }
00236
00237 if((presentationInterval == D3DPRESENT_INTERVAL_DEFAULT) ||
00238 (deviceCapability.PresentationIntervals & presentationInterval)){
00239 presentationInterval_.add(presentationInterval);
00240 }
00241 }
00242
00243
00244 }
00245
00246
00247 String GraphicsDeviceComboInformation::toString(){
00248 String result;
00249
00250 if(isWindowed_){ result += "Window "; }
00251 else{ result += "Fullscreen "; }
00252
00253 GraphicsBufferFormat adapter(adapterFormat_);
00254 GraphicsBufferFormat backBuffer(backBufferFormat_);
00255 String formatString;
00256 formatString.format("adapter %s backBuffer %s ",
00257 adapter.getName().getBytes(), backBuffer.getName().getBytes());
00258 result += formatString;
00259 return result;
00260 }
00261
00262 }
00263