static bool d3d9_cg_load_program(void *data, void *fragment_data, void *vertex_data, const char *prog, bool path_is_file) { bool ret = true; const char *list = NULL; char *listing_f = NULL; char *listing_v = NULL; CGprogram *fPrg = (CGprogram*)fragment_data; CGprogram *vPrg = (CGprogram*)vertex_data; CGprofile vertex_profile = cgD3D9GetLatestVertexProfile(); CGprofile fragment_profile = cgD3D9GetLatestPixelProfile(); const char **fragment_opts = cgD3D9GetOptimalOptions(fragment_profile); const char **vertex_opts = cgD3D9GetOptimalOptions(vertex_profile); cg_renderchain_t *cg_data = (cg_renderchain_t*)data; RARCH_LOG("[D3D Cg]: Vertex profile: %s\n", cgGetProfileString(vertex_profile)); RARCH_LOG("[D3D Cg]: Fragment profile: %s\n", cgGetProfileString(fragment_profile)); if (path_is_file && !string_is_empty(prog)) *fPrg = cgCreateProgramFromFile(cg_data->cgCtx, CG_SOURCE, prog, fragment_profile, "main_fragment", fragment_opts); else *fPrg = cgCreateProgram(cg_data->cgCtx, CG_SOURCE, stock_cg_d3d9_program, fragment_profile, "main_fragment", fragment_opts); list = cgGetLastListing(cg_data->cgCtx); if (list) listing_f = strdup(list); if (path_is_file && !string_is_empty(prog)) *vPrg = cgCreateProgramFromFile(cg_data->cgCtx, CG_SOURCE, prog, vertex_profile, "main_vertex", vertex_opts); else *vPrg = cgCreateProgram(cg_data->cgCtx, CG_SOURCE, stock_cg_d3d9_program, vertex_profile, "main_vertex", vertex_opts); list = cgGetLastListing(cg_data->cgCtx); if (list) listing_v = strdup(list); if (!fPrg || !vPrg) { RARCH_ERR("CG error: %s\n", cgGetErrorString(cgGetError())); if (listing_f) RARCH_ERR("Fragment:\n%s\n", listing_f); else if (listing_v) RARCH_ERR("Vertex:\n%s\n", listing_v); ret = false; goto end; } cgD3D9LoadProgram(*fPrg, true, 0); cgD3D9LoadProgram(*vPrg, true, 0); end: free(listing_f); free(listing_v); return ret; }
static bool renderchain_compile_shaders(cg_renderchain_t *chain, void *fragment_data, void *vertex_data, const std::string &shader) { CGprogram *fPrg = (CGprogram*)fragment_data; CGprogram *vPrg = (CGprogram*)vertex_data; CGprofile vertex_profile = cgD3D9GetLatestVertexProfile(); CGprofile fragment_profile = cgD3D9GetLatestPixelProfile(); const char **fragment_opts = cgD3D9GetOptimalOptions(fragment_profile); const char **vertex_opts = cgD3D9GetOptimalOptions(vertex_profile); RARCH_LOG("[D3D Cg]: Vertex profile: %s\n", cgGetProfileString(vertex_profile)); RARCH_LOG("[D3D Cg]: Fragment profile: %s\n", cgGetProfileString(fragment_profile)); if (shader.length() > 0) { RARCH_LOG("[D3D Cg]: Compiling shader: %s.\n", shader.c_str()); *fPrg = cgCreateProgramFromFile(chain->cgCtx, CG_SOURCE, shader.c_str(), fragment_profile, "main_fragment", fragment_opts); if (cgGetLastListing(chain->cgCtx)) RARCH_ERR("[D3D Cg]: Fragment error:\n%s\n", cgGetLastListing(chain->cgCtx)); *vPrg = cgCreateProgramFromFile(chain->cgCtx, CG_SOURCE, shader.c_str(), vertex_profile, "main_vertex", vertex_opts); if (cgGetLastListing(chain->cgCtx)) RARCH_ERR("[D3D Cg]: Vertex error:\n%s\n", cgGetLastListing(chain->cgCtx)); } else { RARCH_LOG("[D3D Cg]: Compiling stock shader.\n"); *fPrg = cgCreateProgram(chain->cgCtx, CG_SOURCE, stock_program, fragment_profile, "main_fragment", fragment_opts); if (cgGetLastListing(chain->cgCtx)) RARCH_ERR("[D3D Cg]: Fragment error:\n%s\n", cgGetLastListing(chain->cgCtx)); *vPrg = cgCreateProgram(chain->cgCtx, CG_SOURCE, stock_program, vertex_profile, "main_vertex", vertex_opts); if (cgGetLastListing(chain->cgCtx)) RARCH_ERR("[D3D Cg]: Vertex error:\n%s\n", cgGetLastListing(chain->cgCtx)); } if (!fPrg || !vPrg) return false; cgD3D9LoadProgram(*fPrg, true, 0); cgD3D9LoadProgram(*vPrg, true, 0); return true; }
bool RenderChain::compile_shaders(CGprogram &fPrg, CGprogram &vPrg, const std::string &shader) { #ifdef HAVE_CG CGprofile vertex_profile = cgD3D9GetLatestVertexProfile(); CGprofile fragment_profile = cgD3D9GetLatestPixelProfile(); RARCH_LOG("[D3D Cg]: Vertex profile: %s\n", cgGetProfileString(vertex_profile)); RARCH_LOG("[D3D Cg]: Fragment profile: %s\n", cgGetProfileString(fragment_profile)); const char **fragment_opts = cgD3D9GetOptimalOptions(fragment_profile); const char **vertex_opts = cgD3D9GetOptimalOptions(vertex_profile); if (shader.length() > 0) { RARCH_LOG("[D3D Cg]: Compiling shader: %s.\n", shader.c_str()); fPrg = cgCreateProgramFromFile(cgCtx, CG_SOURCE, shader.c_str(), fragment_profile, "main_fragment", fragment_opts); if (cgGetLastListing(cgCtx)) RARCH_ERR("[D3D Cg]: Fragment error:\n%s\n", cgGetLastListing(cgCtx)); vPrg = cgCreateProgramFromFile(cgCtx, CG_SOURCE, shader.c_str(), vertex_profile, "main_vertex", vertex_opts); if (cgGetLastListing(cgCtx)) RARCH_ERR("[D3D Cg]: Vertex error:\n%s\n", cgGetLastListing(cgCtx)); } else { RARCH_LOG("[D3D Cg]: Compiling stock shader.\n"); fPrg = cgCreateProgram(cgCtx, CG_SOURCE, stock_program, fragment_profile, "main_fragment", fragment_opts); if (cgGetLastListing(cgCtx)) RARCH_ERR("[D3D Cg]: Fragment error:\n%s\n", cgGetLastListing(cgCtx)); vPrg = cgCreateProgram(cgCtx, CG_SOURCE, stock_program, vertex_profile, "main_vertex", vertex_opts); if (cgGetLastListing(cgCtx)) RARCH_ERR("[D3D Cg]: Vertex error:\n%s\n", cgGetLastListing(cgCtx)); } if (!fPrg || !vPrg) return false; cgD3D9LoadProgram(fPrg, true, 0); cgD3D9LoadProgram(vPrg, true, 0); #endif return true; }
static void createCgPrograms() { const char **profileOpts; /* Determine the best profile once a device to be set. */ g_cgVertexProfile = cgD3D9GetLatestVertexProfile(); checkForCgError("getting latest profile"); profileOpts = cgD3D9GetOptimalOptions(g_cgVertexProfile); checkForCgError("getting latest profile options"); g_cgVertexProgram = cgCreateProgramFromFile( g_cgContext, /* Cg runtime context */ CG_SOURCE, /* Program in human-readable form */ g_strVertexProgramFileName,/* Name of file containing program */ g_cgVertexProfile, /* Profile: OpenGL ARB vertex program */ g_strVertexProgramName, /* Entry function name */ profileOpts); /* Pass optimal compiler options */ checkForCgError("creating vertex program from file"); //get variable handle g_cgWorldMatrix = cgGetNamedParameter(g_cgVertexProgram, "worldMatrix"); g_cgWorldViewProjMatrix = cgGetNamedParameter(g_cgVertexProgram, "worldViewProjMatrix"); g_cgAmbient = cgGetNamedParameter(g_cgVertexProgram, "ambient"); g_cgLightColor = cgGetNamedParameter(g_cgVertexProgram, "lightColor"); g_cgLightPos = cgGetNamedParameter(g_cgVertexProgram, "lightPos"); g_cgEyePos = cgGetNamedParameter(g_cgVertexProgram, "eyePos"); g_cgKe = cgGetNamedParameter(g_cgVertexProgram, "ke"); g_cgKa = cgGetNamedParameter(g_cgVertexProgram, "ka"); g_cgKd = cgGetNamedParameter(g_cgVertexProgram, "kd"); g_cgKs = cgGetNamedParameter(g_cgVertexProgram, "ks"); g_cgShininess = cgGetNamedParameter(g_cgVertexProgram, "shininess"); assert(g_cgWorldMatrix && g_cgWorldViewProjMatrix && g_cgAmbient && g_cgLightColor && g_cgLightPos && g_cgEyePos && g_cgKe && g_cgKa && g_cgKd && g_cgKs && g_cgShininess); }
FFxProgram::FFxProgram(CGdomain aProfileDomain, const char* aFileName, const char* aEntry, const char** aArgs) : mProgramFlags(0), mProgram(0), mSourceBuffer(0), mProfileDomain(aProfileDomain) { #ifdef WIN32 if (GDD->GetClassID() == ClassIDZDisplayDeviceDX9) mProfile = (aProfileDomain == CG_VERTEX_DOMAIN) ?cgD3D9GetLatestVertexProfile():cgD3D9GetLatestPixelProfile(); else #endif { mProfile = (aProfileDomain == CG_VERTEX_DOMAIN) ?cgGLGetLatestProfile(CG_GL_VERTEX):cgGLGetLatestProfile(CG_GL_FRAGMENT ); cgGLSetOptimalOptions(mProfile); checkForCgError("setprofile"); } mFileName = aFileName; mEntry = aEntry; // FIXME mArgs //mArgs = aArgs; }
static bool d3d9_cg_load_program(void *data, struct shader_pass *pass, const char *prog, bool path_is_file) { const char *list = NULL; char *listing_f = NULL; char *listing_v = NULL; CGprofile vertex_profile = cgD3D9GetLatestVertexProfile(); CGprofile fragment_profile = cgD3D9GetLatestPixelProfile(); const char **fragment_opts = cgD3D9GetOptimalOptions(fragment_profile); const char **vertex_opts = cgD3D9GetOptimalOptions(vertex_profile); cg_renderchain_t *chain = (cg_renderchain_t*)data; CGcontext cgCtx = chain->cgCtx; if ( fragment_profile == CG_PROFILE_UNKNOWN || vertex_profile == CG_PROFILE_UNKNOWN) { RARCH_ERR("Invalid profile type\n"); goto error; } RARCH_LOG("[D3D9 Cg]: Vertex profile: %s\n", cgGetProfileString(vertex_profile)); RARCH_LOG("[D3D9 Cg]: Fragment profile: %s\n", cgGetProfileString(fragment_profile)); if (path_is_file && !string_is_empty(prog)) pass->fprg = cgCreateProgramFromFile(cgCtx, CG_SOURCE, prog, fragment_profile, "main_fragment", fragment_opts); else pass->fprg = cgCreateProgram(cgCtx, CG_SOURCE, stock_cg_d3d9_program, fragment_profile, "main_fragment", fragment_opts); list = cgGetLastListing(cgCtx); if (list) listing_f = strdup(list); if (path_is_file && !string_is_empty(prog)) pass->vprg = cgCreateProgramFromFile(cgCtx, CG_SOURCE, prog, vertex_profile, "main_vertex", vertex_opts); else pass->vprg = cgCreateProgram(cgCtx, CG_SOURCE, stock_cg_d3d9_program, vertex_profile, "main_vertex", vertex_opts); list = cgGetLastListing(cgCtx); if (list) listing_v = strdup(list); if (!pass->fprg || !pass->vprg) goto error; cgD3D9LoadProgram(pass->fprg, true, 0); cgD3D9LoadProgram(pass->vprg, true, 0); free(listing_f); free(listing_v); return true; error: RARCH_ERR("CG error: %s\n", cgGetErrorString(cgGetError())); if (listing_f) RARCH_ERR("Fragment:\n%s\n", listing_f); else if (listing_v) RARCH_ERR("Vertex:\n%s\n", listing_v); free(listing_f); free(listing_v); return false; }
void D3D9Device::init( const ion_uint32 width,const ion_uint32 height, const base::String& title,const bool fullscreen,void* displayhandle, const ion_uint32 adapter, const video::Pixelformat colorbufferformat, const video::Pixelformat depthstencilformat,const ion_uint32 Hz,const bool vsync) { if (!m_IsValid) { base::log("D3D9Device::init()",base::Warning) << "Initializing an invalid device\n"; } openWindow(width,height,title,fullscreen,displayhandle); bool windowed=!m_Fullscreen; D3DFORMAT adapterfmt; if (windowed) { D3DDISPLAYMODE d3ddm; m_pD3D9->GetAdapterDisplayMode(adapter,&d3ddm); adapterfmt=d3ddm.Format; } else adapterfmt=d3dpixelformat(colorbufferformat); if (adapterfmt==D3DFMT_UNKNOWN) { base::log("D3D9Device::init()",base::Error) << "Unknown/unsupported color buffer format\n"; m_IsValid=false; return; } RECT r; GetClientRect(m_hWindow,&r); m_D3DPP.Windowed=windowed; m_D3DPP.BackBufferWidth=r.right-r.left; m_D3DPP.BackBufferHeight=r.bottom-r.top; m_D3DPP.BackBufferCount=1; m_D3DPP.BackBufferFormat=adapterfmt; m_D3DPP.AutoDepthStencilFormat=d3dpixelformat(depthstencilformat); m_D3DPP.EnableAutoDepthStencil=TRUE; m_D3DPP.Flags=0; m_D3DPP.PresentationInterval=vsync ? D3DPRESENT_INTERVAL_DEFAULT : D3DPRESENT_INTERVAL_IMMEDIATE; m_D3DPP.FullScreen_RefreshRateInHz=windowed ? 0 : Hz; m_D3DPP.hDeviceWindow=m_hWindow; m_D3DPP.MultiSampleQuality=0; m_D3DPP.MultiSampleType=D3DMULTISAMPLE_NONE; m_D3DPP.SwapEffect=D3DSWAPEFFECT_DISCARD; m_D3DPP.Windowed=windowed; // Getting caps base::log("D3D9Device::init()",base::Message) << "Getting caps\n"; HRESULT hr=m_pD3D9->GetDeviceCaps(adapter,D3DDEVTYPE_HAL,&m_D3DCaps); if (FAILED(hr)) { base::log("D3D9Device::init()",base::Error) << "GetDeviceCaps() failed\n"; m_IsValid=false; return; } // Caps structure is initialized here { base::log("D3D9Device::init()",base::Message) << "Analyzing caps\n"; m_Caps.m_NPOTTextures=!((m_D3DCaps.TextureCaps&D3DPTEXTURECAPS_POW2) || (m_D3DCaps.TextureCaps&D3DPTEXTURECAPS_NONPOW2CONDITIONAL)); m_Caps.m_RectangularTextures=(m_D3DCaps.TextureCaps&D3DPTEXTURECAPS_SQUAREONLY)==0; m_Caps.m_Cubemaps=(m_D3DCaps.TextureCaps&D3DPTEXTURECAPS_CUBEMAP)!=0; m_Caps.m_NPOTCubemaps=(m_D3DCaps.TextureCaps&D3DPTEXTURECAPS_CUBEMAP_POW2)==0; m_Caps.m_ProjectedTextures=(m_D3DCaps.TextureCaps&D3DPTEXTURECAPS_PROJECTED)!=0; m_Caps.m_DisplacementMaps=false; m_Caps.m_CompressedTextures=false; m_Caps.m_MaxTextureWidth=m_D3DCaps.MaxTextureWidth; m_Caps.m_MaxTextureHeight=m_D3DCaps.MaxTextureHeight; m_Caps.m_MaxTextureVolumeDepth=m_D3DCaps.MaxVolumeExtent; m_Caps.m_MaxAnisotropy=m_D3DCaps.MaxAnisotropy; m_Caps.m_MaxTextureBlendStages=m_D3DCaps.MaxTextureBlendStages; m_Caps.m_MaxActiveFFLights=m_D3DCaps.MaxActiveLights; m_Caps.m_MaxPointSize=m_D3DCaps.MaxPointSize; m_Caps.m_MaxPrimitiveCount=m_D3DCaps.MaxPrimitiveCount; m_Caps.m_MaxVertexIndex=m_D3DCaps.MaxVertexIndex; } // Probing formats { video::Caps::Texflags **pTexflags, *pTexflagarrays[]={m_Caps.m_Valid2DTextureFormats,m_Caps.m_Valid3DTextureFormats, m_Caps.m_ValidCubemapFormats,0}; const D3DRESOURCETYPE rtype[]={D3DRTYPE_TEXTURE,D3DRTYPE_VOLUMETEXTURE,D3DRTYPE_CUBETEXTURE}; pTexflags=pTexflagarrays; unsigned int ii=0; base::log("D3D9Device::init()",base::Message) << "Probing texture formats\n"; while (*pTexflags) { video::Caps::Texflags *pTexflagarray=*pTexflags; for (unsigned int i=0;i<video::Pixelformat_NumFormats;++i) { D3DFORMAT fmt=d3dpixelformat((video::Pixelformat)i); hr=0; hr=m_pD3D9->CheckDeviceFormat(adapter,D3DDEVTYPE_HAL,adapterfmt,0,rtype[ii],fmt); if (FAILED(hr)) { pTexflagarray[i].m_Supported=false; continue; } else pTexflagarray[i].m_Supported=true; if ((i==video::Pixelformat_RGB_DXT1) || (i==video::Pixelformat_RGBA_DXT1) || (i==video::Pixelformat_RGBA_DXT3) || (i==video::Pixelformat_RGBA_DXT5)) m_Caps.m_CompressedTextures=true; // Volume textures are not supported as render targets if (rtype[ii]!=D3DRTYPE_VOLUMETEXTURE) { hr=m_pD3D9->CheckDeviceFormat(adapter,D3DDEVTYPE_HAL,adapterfmt,D3DUSAGE_RENDERTARGET,rtype[ii],fmt); pTexflagarray[i].m_Rendertarget=(hr==D3D_OK); m_Caps.m_Rendertargets=true; } else pTexflagarray[i].m_Rendertarget=false; hr=m_pD3D9->CheckDeviceFormat(adapter,D3DDEVTYPE_HAL,adapterfmt,D3DUSAGE_DYNAMIC,rtype[ii],fmt); pTexflagarray[i].m_Dynamic=(hr==D3D_OK); // For depth buffers, only depth formats are supported // Volume textures are not supported if (isDepthformat((video::Pixelformat)i) && (rtype[ii]!=D3DRTYPE_VOLUMETEXTURE)) { hr=m_pD3D9->CheckDeviceFormat(adapter,D3DDEVTYPE_HAL,adapterfmt,D3DUSAGE_DEPTHSTENCIL,rtype[ii],fmt); pTexflagarray[i].m_Depth=(hr==D3D_OK); } else pTexflagarray[i].m_Depth=false; if ((m_D3DCaps.DevCaps2&D3DDEVCAPS2_DMAPNPATCH)!=0) { hr=m_pD3D9->CheckDeviceFormat(adapter,D3DDEVTYPE_HAL,adapterfmt,D3DUSAGE_DMAP,rtype[ii],fmt); pTexflagarray[i].m_DisplacementMap=(hr==D3D_OK); } else pTexflagarray[i].m_DisplacementMap=false; } ++pTexflags; ++ii; } } base::log("D3D9Device::init()",base::Message) << "Creating D3D device\n"; hr=m_pD3D9->CreateDevice(adapter,D3DDEVTYPE_HAL,m_hWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,&m_D3DPP,&m_pD3DDev9); if (FAILED(hr)) { base::log("D3D9Device::init()",base::Error) << "CreateDevice() failed\n"; m_IsValid=false; return; } D3DVIEWPORT9 viewport; viewport.X=0; viewport.Y=0; viewport.Width=r.right-r.left; viewport.Height=r.bottom-r.top; viewport.MinZ=0; viewport.MaxZ=1; m_pD3DDev9->SetViewport(&viewport); #ifdef D3D9DRV_USE_CG base::log("D3D9Device::init()",base::Message) << "Initializing Cg\n"; { m_CgContext=cgCreateContext(); cgD3D9SetDevice(m_pD3DDev9); #ifdef D3D9DRV_CG_DEBUG_ERRORCALLBACK errctx=m_CgContext; cgSetErrorCallback(cgErrorCallback); #endif m_CgVertexProfile=cgD3D9GetLatestVertexProfile(); m_CgFragmentProfile=cgD3D9GetLatestPixelProfile(); m_CgOptimalVertexProfileOptions=cgD3D9GetOptimalOptions(m_CgVertexProfile); m_CgOptimalFragmentProfileOptions=cgD3D9GetOptimalOptions(m_CgFragmentProfile); } #endif base::log("D3D9Device::init()",base::Message) << "Probing queries\n"; { IDirect3DQuery9* pQuery=0; hr=m_pD3DDev9->CreateQuery(D3DQUERYTYPE_OCCLUSION,&pQuery); m_Caps.m_HWOcclusionQueries=(hr==D3D_OK); if (pQuery) pQuery->Release(); } { base::log("D3D9Device::init()",base::Message) << "Probing vertex program support\n"; // Supported vertex programs { unsigned int version=HIBYTE(LOWORD(m_D3DCaps.VertexShaderVersion)); unsigned int subversion=LOBYTE(LOWORD(m_D3DCaps.VertexShaderVersion)); if (version>=3) { m_Caps.m_SupportedProgramFormats.addString("d3d_vs11"); m_Caps.m_SupportedProgramFormats.addString("d3d_vs20"); m_Caps.m_SupportedProgramFormats.addString("d3d_vs30"); } else if (version>=2) { m_Caps.m_SupportedProgramFormats.addString("d3d_vs11"); if (subversion>=0) m_Caps.m_SupportedProgramFormats.addString("d3d_vs20"); } else if (version>=1) { if (subversion>=1) m_Caps.m_SupportedProgramFormats.addString("d3d_vs11"); } // HLSL support LPCSTR vsprofile=D3DXGetVertexShaderProfile(m_pD3DDev9); base::String hlslvsprofile; if (vsprofile) hlslvsprofile=vsprofile; if (hlslvsprofile.compare("vs_1_1",true)) { m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_vs11"); } else if (hlslvsprofile.compare("vs_2_0",true)) { m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_vs11"); m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_vs20"); } else if (hlslvsprofile.compare("vs_2_a",true)) { m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_vs11"); m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_vs20"); m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_vs2a"); } else if (hlslvsprofile.compare("vs_3_0",true) || (version>=3)) { m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_vs11"); m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_vs20"); m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_vs2a"); m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_vs30"); } #ifdef D3D9DRV_USE_CG m_Caps.m_SupportedProgramFormats.addString("cg_vprogram"); #endif } base::log("D3D9Device::init()",base::Message) << "Probing fragment program support\n"; // Supported fragment programs { unsigned int version=HIBYTE(LOWORD(m_D3DCaps.PixelShaderVersion)); unsigned int subversion=LOBYTE(LOWORD(m_D3DCaps.PixelShaderVersion)); if (version>=3) { m_Caps.m_SupportedProgramFormats.addString("d3d_ps11"); m_Caps.m_SupportedProgramFormats.addString("d3d_ps12"); m_Caps.m_SupportedProgramFormats.addString("d3d_ps13"); m_Caps.m_SupportedProgramFormats.addString("d3d_ps14"); m_Caps.m_SupportedProgramFormats.addString("d3d_ps20"); if (subversion>=0) m_Caps.m_SupportedProgramFormats.addString("d3d_ps30"); } else if (version>=2) { m_Caps.m_SupportedProgramFormats.addString("d3d_ps11"); m_Caps.m_SupportedProgramFormats.addString("d3d_ps12"); m_Caps.m_SupportedProgramFormats.addString("d3d_ps13"); m_Caps.m_SupportedProgramFormats.addString("d3d_ps14"); if (subversion>=0) m_Caps.m_SupportedProgramFormats.addString("d3d_ps20"); } else if (version>=1) { if (subversion>=1) m_Caps.m_SupportedProgramFormats.addString("d3d_ps11"); if (subversion>=2) m_Caps.m_SupportedProgramFormats.addString("d3d_ps12"); if (subversion>=3) m_Caps.m_SupportedProgramFormats.addString("d3d_ps13"); if (subversion>=4) m_Caps.m_SupportedProgramFormats.addString("d3d_ps14"); } // HLSL support LPCSTR vsprofile=D3DXGetPixelShaderProfile(m_pD3DDev9); base::String hlslpsprofile; if (vsprofile) hlslpsprofile=vsprofile; if (hlslpsprofile.compare("ps_1_1",true)) { m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps11"); } else if (hlslpsprofile.compare("ps_1_2",true)) { m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps11"); m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps12"); } else if (hlslpsprofile.compare("ps_1_3",true)) { m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps11"); m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps12"); m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps13"); } else if (hlslpsprofile.compare("ps_1_4",true)) { m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps11"); m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps12"); m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps13"); m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps14"); } else if (hlslpsprofile.compare("ps_2_0",true)) { m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps11"); m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps12"); m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps13"); m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps14"); m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps20"); } else if (hlslpsprofile.compare("ps_2_a",true)) { m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps11"); m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps12"); m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps13"); m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps14"); m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps20"); m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps2a"); } else if (hlslpsprofile.compare("ps_3_0",true) || (version>=3)) { m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps11"); m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps12"); m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps13"); m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps14"); m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps20"); m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps2a"); m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps30"); } #ifdef D3D9DRV_USE_CG m_Caps.m_SupportedProgramFormats.addString("cg_fprogram"); #endif } } // Caps end m_Displaywidth=viewport.Width; m_Displayheight=viewport.Height; m_ColorbufferFormat=colorbufferformat; m_DepthstencilbufferFormat=depthstencilformat; m_pD3DDev9->SetRenderState(D3DRS_FOGVERTEXMODE,D3DFOG_LINEAR); fixedLighting(false); base::log("D3D9Device::init()",base::Message) << "Init complete\n"; }
void CD3D9CgMaterialRenderer::init(s32& pMaterialType, const c8* pVertexProgram, const c8* pVertexEntry, E_VERTEX_SHADER_TYPE pVertexProfile, const c8* pFragmentProgram, const c8* pFragmentEntry, E_PIXEL_SHADER_TYPE pFragmentProfile, const c8* pGeometryProgram, const c8* pGeometryEntry, E_GEOMETRY_SHADER_TYPE pGeometryProfile, scene::E_PRIMITIVE_TYPE pInType, scene::E_PRIMITIVE_TYPE pOutType, u32 pVertices) { bool Status = true; CGerror Error = CG_NO_ERROR; pMaterialType = -1; // TODO: add profile selection if (pVertexProgram) { VertexProfile = cgD3D9GetLatestVertexProfile(); if (VertexProfile) VertexProgram = cgCreateProgram(Driver->getCgContext(), CG_SOURCE, pVertexProgram, VertexProfile, pVertexEntry, 0); if (!VertexProgram) { Error = cgGetError(); os::Printer::log("Cg vertex program failed to compile:", ELL_ERROR); os::Printer::log(cgGetLastListing(Driver->getCgContext()), ELL_ERROR); Status = false; } else cgD3D9LoadProgram(VertexProgram, 0, 0); } if (pFragmentProgram) { FragmentProfile = cgD3D9GetLatestPixelProfile(); if (FragmentProfile) FragmentProgram = cgCreateProgram(Driver->getCgContext(), CG_SOURCE, pFragmentProgram, FragmentProfile, pFragmentEntry, 0); if (!FragmentProgram) { Error = cgGetError(); os::Printer::log("Cg fragment program failed to compile:", ELL_ERROR); os::Printer::log(cgGetLastListing(Driver->getCgContext()), ELL_ERROR); Status = false; } else cgD3D9LoadProgram(FragmentProgram, 0, 0); } /*if (pGeometryProgram) { GeometryProfile = cgD3D9GetLatestGeometryProfile(); if (GeometryProfile) GeometryProgram = cgCreateProgram(Driver->getCgContext(), CG_SOURCE, pGeometryProgram, GeometryProfile, pGeometryEntry, 0); if (!GeometryProgram) { Error = cgGetError(); os::Printer::log("Cg geometry program failed to compile:", ELL_ERROR); os::Printer::log(cgGetLastListing(Driver->getCgContext()), ELL_ERROR); Status = false; } else cgD3D9LoadProgram(GeometryProgram, 0, 0); }*/ getUniformList(); // create D3D9 specifics sampler uniforms. for(unsigned int i = 0; i < UniformInfo.size(); ++i) { if (UniformInfo[i]->getType() == CG_SAMPLER2D) { bool IsGlobal = true; if (UniformInfo[i]->getSpace() == CG_PROGRAM) IsGlobal = false; CCgUniform* Uniform = new CD3D9CgUniformSampler2D(UniformInfo[i]->getParameter(), IsGlobal); delete UniformInfo[i]; UniformInfo[i] = Uniform; } } if (Status) pMaterialType = Driver->addMaterialRenderer(this); }
bool CD3DCG::LoadShader(const TCHAR *shaderFile) { CCGShader cgShader; TCHAR shaderPath[MAX_PATH]; TCHAR tempPath[MAX_PATH]; HRESULT hr; GLenum error; ClearPasses(); if (shaderFile == NULL || *shaderFile==TEXT('\0')) return true; lstrcpy(shaderPath,shaderFile); for(int i=lstrlen(shaderPath); i>=0; i--){ if(IS_SLASH(shaderPath[i])){ shaderPath[i]=TEXT('\0'); break; } } SetCurrentDirectory(shaderPath); if(!cgShader.LoadShader(_tToChar(shaderFile))) return false; CGprofile vertexProfile = cgD3D9GetLatestVertexProfile(); CGprofile pixelProfile = cgD3D9GetLatestPixelProfile(); const char** vertexOptions = cgD3D9GetOptimalOptions(vertexProfile); const char** pixelOptions = cgD3D9GetOptimalOptions(pixelProfile); shaderPasses.push_back(shaderPass()); for(CCGShader::passVector::iterator it=cgShader.shaderPasses.begin(); it!=cgShader.shaderPasses.end();it++) { shaderPass pass; pass.scaleParams = it->scaleParams; /* if this is the last pass (the only one that can have CG_SCALE_NONE) and no filter has been set use the GUI setting */ if(pass.scaleParams.scaleTypeX==CG_SCALE_NONE && !it->filterSet) { pass.linearFilter = GUI.BilinearFilter; } else { pass.linearFilter = it->linearFilter; } // paths in the meta file can be relative _tfullpath(tempPath,_tFromChar(it->cgShaderFile),MAX_PATH); char *fileContents = ReadShaderFileContents(tempPath); if(!fileContents) return false; pass.cgVertexProgram = cgCreateProgram( cgContext, CG_SOURCE, fileContents, vertexProfile, "main_vertex", vertexOptions); checkForCgError("Compiling vertex program"); pass.cgFragmentProgram = cgCreateProgram( cgContext, CG_SOURCE, fileContents, pixelProfile, "main_fragment", pixelOptions); checkForCgError("Compiling fragment program"); delete [] fileContents; if(!pass.cgVertexProgram || !pass.cgFragmentProgram) { return false; } if(pass.cgVertexProgram) { hr = cgD3D9LoadProgram(pass.cgVertexProgram,false,0); } checkForCgError("Loading vertex program"); if(pass.cgFragmentProgram) { hr = cgD3D9LoadProgram(pass.cgFragmentProgram,false,0); } checkForCgError("Loading fragment program"); /* generate vertex buffer */ hr = pDevice->CreateVertexBuffer(sizeof(VERTEX)*4,D3DUSAGE_WRITEONLY,0,D3DPOOL_MANAGED,&pass.vertexBuffer,NULL); if(FAILED(hr)) { pass.vertexBuffer = NULL; DXTRACE_ERR_MSGBOX(TEXT("Error creating vertex buffer"), hr); return false; } /* set up vertex declarations for the pass, this also creates the vertex declaration */ setupVertexDeclaration(pass); shaderPasses.push_back(pass); } for(std::vector<CCGShader::lookupTexture>::iterator it=cgShader.lookupTextures.begin();it!=cgShader.lookupTextures.end();it++) { lookupTexture tex; strcpy(tex.id,it->id); tex.linearFilter = it->linearfilter; _tfullpath(tempPath,_tFromChar(it->texturePath),MAX_PATH); hr = D3DXCreateTextureFromFileEx( pDevice, tempPath, D3DX_DEFAULT_NONPOW2, D3DX_DEFAULT_NONPOW2, 0, 0, D3DFMT_FROM_FILE, D3DPOOL_MANAGED, it->linearfilter?D3DX_FILTER_LINEAR:D3DX_FILTER_POINT, 0, 0, NULL, NULL, &tex.tex); if FAILED(hr){ tex.tex = NULL; } lookupTextures.push_back(tex); } shaderLoaded = true; return true; }