mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 16:58:40 -04:00
This fixes most issues with Cg's GLSL profiles on non-NVIDIA cards
This commit is contained in:
parent
3aefaff8b1
commit
3b1bd9ef39
@ -84,7 +84,9 @@ D3DMATRIX DXGraphicsStateGuardian9::_d3d_ident_mat;
|
||||
unsigned char *DXGraphicsStateGuardian9::_temp_buffer = NULL;
|
||||
unsigned char *DXGraphicsStateGuardian9::_safe_buffer_start = NULL;
|
||||
|
||||
#ifdef HAVE_CG
|
||||
LPDIRECT3DDEVICE9 DXGraphicsStateGuardian9::_cg_device = NULL;
|
||||
#endif
|
||||
|
||||
#define __D3DLIGHT_RANGE_MAX ((PN_stdfloat)sqrt(FLT_MAX)) //for some reason this is missing in dx9 hdrs
|
||||
|
||||
@ -150,6 +152,10 @@ DXGraphicsStateGuardian9(GraphicsEngine *engine, GraphicsPipe *pipe) :
|
||||
|
||||
_supports_stream_offset = false;
|
||||
|
||||
#ifdef HAVE_CG
|
||||
_cg_context = 0;
|
||||
#endif
|
||||
|
||||
get_gamma_table();
|
||||
atexit (atexit_function);
|
||||
}
|
||||
@ -2372,6 +2378,8 @@ reset() {
|
||||
#ifdef HAVE_CG
|
||||
set_cg_device(_d3d_device);
|
||||
|
||||
_cg_context = cgCreateContext();
|
||||
|
||||
if (cgD3D9IsProfileSupported(CG_PROFILE_PS_2_0) &&
|
||||
cgD3D9IsProfileSupported(CG_PROFILE_VS_2_0)) {
|
||||
_supports_basic_shaders = true;
|
||||
@ -2388,7 +2396,6 @@ reset() {
|
||||
}
|
||||
|
||||
if (dxgsg9_cat.is_debug()) {
|
||||
|
||||
CGprofile vertex_profile;
|
||||
CGprofile pixel_profile;
|
||||
|
||||
@ -2408,8 +2415,8 @@ reset() {
|
||||
}
|
||||
|
||||
dxgsg9_cat.debug()
|
||||
<< "\nCg vertex profile = " << vertex_profile_str << " id = " << vertex_profile
|
||||
<< "\nCg pixel profile = " << pixel_profile_str << " id = " << pixel_profile
|
||||
<< "\nCg latest vertex profile = " << vertex_profile_str << " id = " << vertex_profile
|
||||
<< "\nCg latest pixel profile = " << pixel_profile_str << " id = " << pixel_profile
|
||||
<< "\nshader model = " << _shader_model
|
||||
<< "\n";
|
||||
}
|
||||
@ -4152,6 +4159,12 @@ close_gsg() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian9::
|
||||
free_nondx_resources() {
|
||||
#ifdef HAVE_CG
|
||||
if (_cg_context) {
|
||||
cgDestroyContext(_cg_context);
|
||||
_cg_context = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -5628,9 +5641,6 @@ set_cg_device(LPDIRECT3DDEVICE9 cg_device) {
|
||||
#endif // HAVE_CG
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
typedef string KEY;
|
||||
|
||||
typedef struct _KEY_ELEMENT
|
||||
|
@ -377,7 +377,10 @@ protected:
|
||||
|
||||
int _supports_gamma_calibration;
|
||||
|
||||
#ifdef HAVE_CG
|
||||
CGcontext _cg_context;
|
||||
static LPDIRECT3DDEVICE9 _cg_device;
|
||||
#endif
|
||||
|
||||
public:
|
||||
virtual TypeHandle get_type() const {
|
||||
|
@ -12,6 +12,7 @@
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXShaderContext9::valid
|
||||
// Access: Public
|
||||
@ -22,12 +23,10 @@
|
||||
// or if no shader languages are compiled into panda.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool CLP(ShaderContext)::
|
||||
valid (GSG *gsg) {
|
||||
valid(GSG *gsg) {
|
||||
#ifdef HAVE_CG
|
||||
if (_cg_context) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return (_cg_program != 0);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -22,8 +22,9 @@
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifdef HAVE_CG
|
||||
#include "Cg/cgD3D9.h"
|
||||
#include <Cg/cgD3D9.h>
|
||||
#endif
|
||||
|
||||
#define DEBUG_SHADER 0
|
||||
@ -37,89 +38,42 @@ TypeHandle CLP(ShaderContext)::_type_handle;
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CLP(ShaderContext)::
|
||||
CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
|
||||
|
||||
_vertex_element_array = NULL;
|
||||
_vertex_declaration = NULL;
|
||||
|
||||
_num_bound_streams = 0;
|
||||
|
||||
_name = s->get_filename ( );
|
||||
_name = s->get_filename();
|
||||
|
||||
#ifdef HAVE_CG
|
||||
_cg_context = 0;
|
||||
CGcontext context = DCAST(DXGraphicsStateGuardian9, gsg)->_cg_context;
|
||||
|
||||
if (s->get_language() == Shader::SL_Cg) {
|
||||
|
||||
// Ask the shader to compile itself for us and
|
||||
// to give us the resulting Cg program objects.
|
||||
|
||||
if (!s->cg_compile_for(gsg->_shader_caps,
|
||||
_cg_context,
|
||||
_cg_vprogram,
|
||||
_cg_fprogram,
|
||||
_cg_gprogram, // CG2 CHANGE
|
||||
_cg_parameter_map)) {
|
||||
if (!s->cg_compile_for(gsg->_shader_caps, context,
|
||||
_cg_program, _cg_parameter_map)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Load the program.
|
||||
|
||||
BOOL paramater_shadowing;
|
||||
DWORD assembly_flags;
|
||||
|
||||
paramater_shadowing = FALSE;
|
||||
assembly_flags = 0;
|
||||
|
||||
DWORD assembly_flags = 0;
|
||||
#if DEBUG_SHADER
|
||||
assembly_flags |= D3DXSHADER_DEBUG;
|
||||
#endif
|
||||
|
||||
HRESULT hr;
|
||||
bool success = true;
|
||||
hr = cgD3D9LoadProgram(_cg_vprogram, paramater_shadowing, assembly_flags);
|
||||
hr = cgD3D9LoadProgram(_cg_program, FALSE, assembly_flags);
|
||||
if (FAILED (hr)) {
|
||||
dxgsg9_cat.error()
|
||||
<< "vertex shader cgD3D9LoadProgram failed "
|
||||
<< D3DERRORSTRING(hr);
|
||||
<< "cgD3D9LoadProgram failed " << D3DERRORSTRING(hr);
|
||||
|
||||
CGerror error = cgGetError();
|
||||
if (error != CG_NO_ERROR) {
|
||||
dxgsg9_cat.error() << " CG ERROR: " << cgGetErrorString(error) << "\n";
|
||||
}
|
||||
success = false;
|
||||
}
|
||||
|
||||
hr = cgD3D9LoadProgram(_cg_fprogram, paramater_shadowing, assembly_flags);
|
||||
if (FAILED (hr)) {
|
||||
dxgsg9_cat.error()
|
||||
<< "pixel shader cgD3D9LoadProgram failed "
|
||||
<< D3DERRORSTRING(hr);
|
||||
|
||||
CGerror error = cgGetError();
|
||||
if (error != CG_NO_ERROR) {
|
||||
dxgsg9_cat.error() << " CG ERROR: " << cgGetErrorString(error) << "\n";
|
||||
}
|
||||
success = false;
|
||||
}
|
||||
|
||||
// BEGIN CG2 CHANGE
|
||||
if (_cg_gprogram != 0)
|
||||
{
|
||||
hr = cgD3D9LoadProgram(_cg_gprogram, paramater_shadowing, assembly_flags);
|
||||
if (FAILED (hr)) {
|
||||
dxgsg9_cat.error()
|
||||
<< "geometry shader cgD3D9LoadProgram failed "
|
||||
<< D3DERRORSTRING(hr);
|
||||
|
||||
CGerror error = cgGetError();
|
||||
if (error != CG_NO_ERROR) {
|
||||
dxgsg9_cat.error() << " CG ERROR: " << cgGetErrorString(error) << "\n";
|
||||
}
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
// END CG2 CHANGE
|
||||
|
||||
if (!success) {
|
||||
release_resources();
|
||||
}
|
||||
}
|
||||
@ -203,12 +157,9 @@ CLP(ShaderContext)::
|
||||
void CLP(ShaderContext)::
|
||||
release_resources() {
|
||||
#ifdef HAVE_CG
|
||||
if (_cg_context) {
|
||||
cgDestroyContext(_cg_context);
|
||||
_cg_context = 0;
|
||||
_cg_vprogram = 0;
|
||||
_cg_fprogram = 0;
|
||||
_cg_gprogram = 0; // CG2 CHANGE
|
||||
if (_cg_program) {
|
||||
cgDestroyProgram(_cg_program);
|
||||
_cg_program = 0;
|
||||
_cg_parameter_map.clear();
|
||||
}
|
||||
#endif
|
||||
@ -228,11 +179,10 @@ release_resources() {
|
||||
bool CLP(ShaderContext)::
|
||||
bind(GSG *gsg) {
|
||||
|
||||
bool bind_state;
|
||||
bool bind_state = false;
|
||||
|
||||
bind_state = false;
|
||||
#ifdef HAVE_CG
|
||||
if (_cg_context) {
|
||||
if (_cg_program) {
|
||||
// clear the last cached FVF to make sure the next SetFVF call goes through
|
||||
|
||||
gsg -> _last_fvf = 0;
|
||||
@ -244,9 +194,9 @@ bind(GSG *gsg) {
|
||||
|
||||
// Bind the shaders.
|
||||
bind_state = true;
|
||||
hr = cgD3D9BindProgram(_cg_vprogram);
|
||||
hr = cgD3D9BindProgram(_cg_program);
|
||||
if (FAILED (hr)) {
|
||||
dxgsg9_cat.error() << "cgD3D9BindProgram vertex shader failed " << D3DERRORSTRING(hr);
|
||||
dxgsg9_cat.error() << "cgD3D9BindProgram failed " << D3DERRORSTRING(hr);
|
||||
|
||||
CGerror error = cgGetError();
|
||||
if (error != CG_NO_ERROR) {
|
||||
@ -255,34 +205,6 @@ bind(GSG *gsg) {
|
||||
|
||||
bind_state = false;
|
||||
}
|
||||
hr = cgD3D9BindProgram(_cg_fprogram);
|
||||
if (FAILED (hr)) {
|
||||
dxgsg9_cat.error() << "cgD3D9BindProgram pixel shader failed " << D3DERRORSTRING(hr);
|
||||
|
||||
CGerror error = cgGetError();
|
||||
if (error != CG_NO_ERROR) {
|
||||
dxgsg9_cat.error() << " CG ERROR: " << cgGetErrorString(error) << "\n";
|
||||
}
|
||||
|
||||
bind_state = false;
|
||||
}
|
||||
|
||||
// BEGIN CG2 CHANGE
|
||||
if (_cg_gprogram != 0)
|
||||
{
|
||||
hr = cgD3D9BindProgram(_cg_gprogram);
|
||||
if (FAILED (hr)) {
|
||||
dxgsg9_cat.error() << "cgD3D9BindProgram geometry shader failed " << D3DERRORSTRING(hr);
|
||||
|
||||
CGerror error = cgGetError();
|
||||
if (error != CG_NO_ERROR) {
|
||||
dxgsg9_cat.error() << " CG ERROR: " << cgGetErrorString(error) << "\n";
|
||||
}
|
||||
|
||||
bind_state = false;
|
||||
}
|
||||
}
|
||||
// END CG2 CHANGE
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -298,18 +220,12 @@ void CLP(ShaderContext)::
|
||||
unbind(GSG *gsg) {
|
||||
|
||||
#ifdef HAVE_CG
|
||||
if (_cg_context) {
|
||||
if (_cg_program) {
|
||||
HRESULT hr;
|
||||
|
||||
hr = gsg -> _d3d_device -> SetVertexShader (NULL);
|
||||
if (FAILED (hr)) {
|
||||
hr = cgD3D9UnbindProgram(_cg_program);
|
||||
if (FAILED(hr)) {
|
||||
dxgsg9_cat.error()
|
||||
<< "SetVertexShader (NULL) failed " << D3DERRORSTRING(hr);
|
||||
}
|
||||
hr = gsg -> _d3d_device -> SetPixelShader (NULL);
|
||||
if (FAILED (hr)) {
|
||||
dxgsg9_cat.error()
|
||||
<< "SetPixelShader (NULL) failed " << D3DERRORSTRING(hr);
|
||||
<< "cgD3D9UnbindProgram failed " << D3DERRORSTRING(hr);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -339,10 +255,9 @@ InternalName *global_internal_name_1 = 0;
|
||||
#endif
|
||||
|
||||
void CLP(ShaderContext)::
|
||||
issue_parameters(GSG *gsg, int altered)
|
||||
{
|
||||
issue_parameters(GSG *gsg, int altered) {
|
||||
#ifdef HAVE_CG
|
||||
if (_cg_context) {
|
||||
if (_cg_program) {
|
||||
|
||||
// Iterate through _ptr parameters
|
||||
for (int i=0; i<(int)_shader->_ptr_spec.size(); i++) {
|
||||
@ -510,7 +425,7 @@ bool CLP(ShaderContext)::
|
||||
update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg, bool force) {
|
||||
if (prev) prev->disable_shader_vertex_arrays(gsg);
|
||||
#ifdef HAVE_CG
|
||||
if (!_cg_context) {
|
||||
if (!_cg_program) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -717,11 +632,11 @@ update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg, bool force) {
|
||||
|
||||
if (( _vertex_element_array != NULL ) &&
|
||||
( _vertex_element_array->add_end_vertex_element() != false )) {
|
||||
if ( dxgsg9_cat.is_debug() ) {
|
||||
if (dxgsg9_cat.is_debug()) {
|
||||
// Note that the currently generated vertex declaration works but never validates.
|
||||
// My theory is that this is due to the shader programs always using float4 whereas
|
||||
// the vertex declaration correctly sets the number of inputs (float2, float3, etc.).
|
||||
if (cgD3D9ValidateVertexDeclaration(_cg_vprogram,
|
||||
if (cgD3D9ValidateVertexDeclaration(_cg_program,
|
||||
_vertex_element_array->_vertex_element_array) == CG_TRUE) {
|
||||
dxgsg9_cat.debug() << "cgD3D9ValidateVertexDeclaration succeeded\n";
|
||||
} else {
|
||||
@ -763,7 +678,7 @@ void CLP(ShaderContext)::
|
||||
disable_shader_texture_bindings(GSG *gsg)
|
||||
{
|
||||
#ifdef HAVE_CG
|
||||
if (_cg_context) {
|
||||
if (_cg_program) {
|
||||
for (int i=0; i<(int)_shader->_tex_spec.size(); i++) {
|
||||
CGparameter p = _cg_parameter_map[_shader->_tex_spec[i]._id._seqno];
|
||||
if (p == NULL) {
|
||||
@ -803,7 +718,7 @@ update_shader_texture_bindings(CLP(ShaderContext) *prev, GSG *gsg)
|
||||
if (prev) prev->disable_shader_texture_bindings(gsg);
|
||||
|
||||
#ifdef HAVE_CG
|
||||
if (_cg_context) {
|
||||
if (_cg_program) {
|
||||
|
||||
for (int i=0; i<(int)_shader->_tex_spec.size(); i++) {
|
||||
CGparameter p = _cg_parameter_map[_shader->_tex_spec[i]._id._seqno];
|
||||
|
@ -22,11 +22,9 @@
|
||||
#include "shader.h"
|
||||
#include "shaderContext.h"
|
||||
|
||||
|
||||
#define CLP(name) DX##name##9
|
||||
#define CLASSPREFIX_QUOTED "DX"
|
||||
|
||||
|
||||
class VertexElementArray;
|
||||
class CLP(GraphicsStateGuardian);
|
||||
|
||||
@ -41,7 +39,7 @@ class CLP(GraphicsStateGuardian);
|
||||
// D3DXCONSTANT_DESC *constant_description_array;
|
||||
// }
|
||||
// DX_PARAMETER;
|
||||
//
|
||||
//
|
||||
// typedef struct
|
||||
// {
|
||||
// int state;
|
||||
@ -52,7 +50,7 @@ class CLP(GraphicsStateGuardian);
|
||||
// };
|
||||
// LPD3DXCONSTANTTABLE constant_table;
|
||||
// D3DXCONSTANTTABLE_DESC constant_table_description;
|
||||
//
|
||||
//
|
||||
// int total_semantics;
|
||||
// D3DXSEMANTIC *semantic_array;
|
||||
// }
|
||||
@ -62,11 +60,10 @@ class CLP(GraphicsStateGuardian);
|
||||
// Class : DXShaderContext9
|
||||
// Description : xyz
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
class EXPCL_PANDADX CLP(ShaderContext): public ShaderContext {
|
||||
class EXPCL_PANDADX CLP(ShaderContext) : public ShaderContext {
|
||||
public:
|
||||
typedef CLP(GraphicsStateGuardian) GSG;
|
||||
|
||||
|
||||
CLP(ShaderContext)(Shader *s, GSG *gsg);
|
||||
~CLP(ShaderContext)();
|
||||
|
||||
@ -88,23 +85,14 @@ public:
|
||||
|
||||
// FOR DEBUGGING
|
||||
string _name;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
#ifdef HAVE_CG
|
||||
CGcontext _cg_context;
|
||||
CGprogram _cg_vprogram;
|
||||
CGprogram _cg_fprogram;
|
||||
|
||||
// BEGIN CG2 CHANGE
|
||||
CGprogram _cg_gprogram; // Geometry program
|
||||
// END CG2 CHANGE
|
||||
|
||||
CGprogram _cg_program;
|
||||
pvector <CGparameter> _cg_parameter_map;
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
void release_resources(void);
|
||||
|
||||
public:
|
||||
|
@ -27,8 +27,7 @@ INLINE bool CLP(CgShaderContext)::
|
||||
valid() {
|
||||
if (_shader->get_error_flag()) return false;
|
||||
if (_shader->get_language() != Shader::SL_Cg) return false;
|
||||
if (_cg_context) return true;
|
||||
return false;
|
||||
return (_cg_program != 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -40,63 +40,40 @@ TypeHandle CLP(CgShaderContext)::_type_handle;
|
||||
CLP(CgShaderContext)::
|
||||
CLP(CgShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext(s) {
|
||||
_glgsg = glgsg;
|
||||
_cg_context = 0;
|
||||
_cg_vprogram = 0;
|
||||
_cg_fprogram = 0;
|
||||
_cg_gprogram = 0;
|
||||
_cg_vprofile = CG_PROFILE_UNKNOWN;
|
||||
_cg_fprofile = CG_PROFILE_UNKNOWN;
|
||||
_cg_gprofile = CG_PROFILE_UNKNOWN;
|
||||
_cg_program = 0;
|
||||
_glsl_profile = false;
|
||||
|
||||
nassertv(s->get_language() == Shader::SL_Cg);
|
||||
|
||||
CGcontext context = _glgsg->_cg_context;
|
||||
|
||||
// Ask the shader to compile itself for us and
|
||||
// to give us the resulting Cg program objects.
|
||||
if (!s->cg_compile_for(_glgsg->_shader_caps,
|
||||
_cg_context,
|
||||
_cg_vprogram,
|
||||
_cg_fprogram,
|
||||
_cg_gprogram,
|
||||
_cg_parameter_map)) {
|
||||
if (!s->cg_compile_for(_glgsg->_shader_caps, context,
|
||||
_cg_program, _cg_parameter_map)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Load the program.
|
||||
if (_cg_vprogram != 0) {
|
||||
_cg_vprofile = cgGetProgramProfile(_cg_vprogram);
|
||||
cgGLLoadProgram(_cg_vprogram);
|
||||
CGerror verror = cgGetError();
|
||||
if (verror != CG_NO_ERROR) {
|
||||
const char *str = cgGetErrorString(verror);
|
||||
GLCAT.error()
|
||||
<< "Could not load Cg vertex program: " << s->get_filename(Shader::ST_vertex)
|
||||
<< " (" << cgGetProfileString(_cg_vprofile) << " " << str << ")\n";
|
||||
release_resources();
|
||||
}
|
||||
}
|
||||
if (_cg_program == 0) {
|
||||
const char *str = cgGetErrorString(cgGetError());
|
||||
GLCAT.error()
|
||||
<< "Could not combine Cg program: " << s->get_filename()
|
||||
<< " (" << str << ")\n";
|
||||
release_resources();
|
||||
|
||||
if (_cg_fprogram != 0) {
|
||||
_cg_fprofile = cgGetProgramProfile(_cg_fprogram);
|
||||
cgGLLoadProgram(_cg_fprogram);
|
||||
CGerror ferror = cgGetError();
|
||||
if (ferror != CG_NO_ERROR) {
|
||||
const char *str = cgGetErrorString(ferror);
|
||||
GLCAT.error()
|
||||
<< "Could not load Cg fragment program: " << s->get_filename(Shader::ST_fragment)
|
||||
<< " (" << cgGetProfileString(_cg_fprofile) << " " << str << ")\n";
|
||||
release_resources();
|
||||
} else {
|
||||
if (cgGetProgramProfile(_cg_program) == CG_PROFILE_GLSLC) {
|
||||
_glsl_profile = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (_cg_gprogram != 0) {
|
||||
_cg_gprofile = cgGetProgramProfile(_cg_gprogram);
|
||||
cgGLLoadProgram(_cg_gprogram);
|
||||
CGerror gerror = cgGetError();
|
||||
if (gerror != CG_NO_ERROR) {
|
||||
const char *str = cgGetErrorString(gerror);
|
||||
cgGLLoadProgram(_cg_program);
|
||||
CGerror error = cgGetError();
|
||||
if (error != CG_NO_ERROR) {
|
||||
const char *str = cgGetErrorString(error);
|
||||
GLCAT.error()
|
||||
<< "Could not load Cg geometry program: " << s->get_filename(Shader::ST_geometry)
|
||||
<< " (" << cgGetProfileString(_cg_gprofile) << " " << str << ")\n";
|
||||
<< "Could not load program: " << s->get_filename()
|
||||
<< " (" << str << ")\n";
|
||||
release_resources();
|
||||
}
|
||||
}
|
||||
@ -122,20 +99,14 @@ CLP(CgShaderContext)::
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(CgShaderContext)::
|
||||
release_resources() {
|
||||
if (_cg_context) {
|
||||
cgDestroyContext(_cg_context);
|
||||
_cg_context = 0;
|
||||
// Do *NOT* destroy the programs here! It causes problems.
|
||||
// if (_cg_vprogram != 0) cgDestroyProgram(_cg_vprogram);
|
||||
// if (_cg_fprogram != 0) cgDestroyProgram(_cg_fprogram);
|
||||
// if (_cg_gprogram != 0) cgDestroyProgram(_cg_gprogram);
|
||||
_cg_vprogram = 0;
|
||||
_cg_fprogram = 0;
|
||||
_cg_gprogram = 0;
|
||||
_cg_parameter_map.clear();
|
||||
if (_cg_program != 0) {
|
||||
cgDestroyProgram(_cg_program);
|
||||
_cg_program = 0;
|
||||
}
|
||||
_cg_parameter_map.clear();
|
||||
if (_glgsg) {
|
||||
_glgsg->report_my_gl_errors();
|
||||
|
||||
} else if (glGetError() != GL_NO_ERROR) {
|
||||
GLCAT.error() << "GL error in ShaderContext destructor\n";
|
||||
}
|
||||
@ -155,25 +126,15 @@ release_resources() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(CgShaderContext)::
|
||||
bind(bool reissue_parameters) {
|
||||
if (reissue_parameters) {
|
||||
// Pass in k-parameters and transform-parameters
|
||||
issue_parameters(Shader::SSD_general);
|
||||
}
|
||||
if (_cg_program != 0) {
|
||||
if (reissue_parameters) {
|
||||
// Pass in k-parameters and transform-parameters
|
||||
issue_parameters(Shader::SSD_general);
|
||||
}
|
||||
|
||||
if (_cg_context != 0) {
|
||||
// Bind the shaders.
|
||||
if (_cg_vprogram != 0) {
|
||||
cgGLEnableProfile(_cg_vprofile);
|
||||
cgGLBindProgram(_cg_vprogram);
|
||||
}
|
||||
if (_cg_fprogram != 0) {
|
||||
cgGLEnableProfile(_cg_fprofile);
|
||||
cgGLBindProgram(_cg_fprogram);
|
||||
}
|
||||
if (_cg_gprogram != 0) {
|
||||
cgGLEnableProfile(_cg_gprofile);
|
||||
cgGLBindProgram(_cg_gprogram);
|
||||
}
|
||||
cgGLEnableProgramProfiles(_cg_program);
|
||||
cgGLBindProgram(_cg_program);
|
||||
|
||||
cg_report_errors();
|
||||
_glgsg->report_my_gl_errors();
|
||||
@ -187,18 +148,12 @@ bind(bool reissue_parameters) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(CgShaderContext)::
|
||||
unbind() {
|
||||
if (_cg_context != 0) {
|
||||
if (_cg_vprogram != 0) {
|
||||
cgGLUnbindProgram(_cg_vprofile);
|
||||
cgGLDisableProfile(_cg_vprofile);
|
||||
}
|
||||
if (_cg_fprogram != 0) {
|
||||
cgGLUnbindProgram(_cg_fprofile);
|
||||
cgGLDisableProfile(_cg_fprofile);
|
||||
}
|
||||
if (_cg_gprogram != 0) {
|
||||
cgGLUnbindProgram(_cg_gprofile);
|
||||
cgGLDisableProfile(_cg_gprofile);
|
||||
if (_cg_program != 0) {
|
||||
int num_domains = cgGetNumProgramDomains(_cg_program);
|
||||
for (int i = 0; i < num_domains; ++i) {
|
||||
CGprofile profile = cgGetProgramDomainProfile(_cg_program, i);
|
||||
cgGLUnbindProgram(profile);
|
||||
cgGLDisableProfile(profile);
|
||||
}
|
||||
|
||||
cg_report_errors();
|
||||
@ -396,7 +351,25 @@ disable_shader_vertex_arrays() {
|
||||
for (int i=0; i<(int)_shader->_var_spec.size(); i++) {
|
||||
CGparameter p = _cg_parameter_map[_shader->_var_spec[i]._id._seqno];
|
||||
if (p == 0) continue;
|
||||
cgGLDisableClientState(p);
|
||||
|
||||
if (_glsl_profile && cgGetParameterBaseResource(p) == CG_ATTR0) {
|
||||
int index = cgGetParameterResourceIndex(p);
|
||||
if (index >= 8) {
|
||||
_glgsg->_glClientActiveTexture(GL_TEXTURE0 + (index - 8));
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
} else if (index == 0) {
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
|
||||
} else if (index == 2) {
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
|
||||
} else if (index == 3) {
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
}
|
||||
} else {
|
||||
cgGLDisableClientState(p);
|
||||
}
|
||||
}
|
||||
|
||||
cg_report_errors();
|
||||
@ -464,20 +437,68 @@ update_shader_vertex_arrays(ShaderContext *prev, bool force) {
|
||||
CGparameter p = _cg_parameter_map[_shader->_var_spec[i]._id._seqno];
|
||||
|
||||
if (numeric_type == GeomEnums::NT_packed_dabc) {
|
||||
cgGLSetParameterPointer(p, GL_BGRA, GL_UNSIGNED_BYTE,
|
||||
stride, client_pointer + start);
|
||||
// Yes, this is a thing.
|
||||
num_values = GL_BGRA;
|
||||
}
|
||||
|
||||
// This is truly the most preposterous hack. When using the GLSL
|
||||
// profiles, cgGLSetParameterPointer relies on the the driver mapping
|
||||
// standard attributes to fixed indices (and breaking the spec doing
|
||||
// so), which only the NVIDIA drivers do. Unbelievable.
|
||||
if (_glsl_profile && cgGetParameterBaseResource(p) == CG_ATTR0) {
|
||||
int index = cgGetParameterResourceIndex(p);
|
||||
switch (index) {
|
||||
case 0: // gl_Vertex
|
||||
glVertexPointer(num_values, _glgsg->get_numeric_type(numeric_type),
|
||||
stride, client_pointer + start);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
break;
|
||||
|
||||
case 2: // gl_Normal
|
||||
glNormalPointer(_glgsg->get_numeric_type(numeric_type),
|
||||
stride, client_pointer + start);
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
break;
|
||||
|
||||
case 3: // gl_Color
|
||||
glColorPointer(num_values, _glgsg->get_numeric_type(numeric_type),
|
||||
stride, client_pointer + start);
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
break;
|
||||
|
||||
case 4: // gl_SecondaryColor
|
||||
//glSecondaryColorPointer(num_values, _glgsg->get_numeric_type(numeric_type),
|
||||
// stride, client_pointer + start);
|
||||
//glEnableClientState(GL_SECONDARY_COLOR_ARRAY);
|
||||
//break;
|
||||
case 5: // gl_FogCoord
|
||||
case 6: // PSIZE?
|
||||
case 7: // BLENDINDICES?
|
||||
case 1: // glWeightPointerARB?
|
||||
GLCAT.error()
|
||||
<< "Unable to bind " << *name << " to "
|
||||
<< cgGetParameterResourceName(p) << "\n";
|
||||
break;
|
||||
|
||||
default:
|
||||
_glgsg->_glClientActiveTexture(GL_TEXTURE0 + (index - 8));
|
||||
glTexCoordPointer(num_values, _glgsg->get_numeric_type(numeric_type),
|
||||
stride, client_pointer + start);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (name == InternalName::get_normal() && num_values == 4) {
|
||||
// In some cases, the normals are aligned to 4 values.
|
||||
// This would cause an error on some rivers, so we tell it
|
||||
// to use the first three values only.
|
||||
// In some cases, the normals are aligned to 4 values. We tell
|
||||
// it to use three values exactly, otherwise we get the error:
|
||||
// An unsupported GL extension was required to perform this operation.
|
||||
num_values = 3;
|
||||
}
|
||||
cgGLSetParameterPointer(p,
|
||||
num_values, _glgsg->get_numeric_type(numeric_type),
|
||||
cgGLSetParameterPointer(p, num_values,
|
||||
_glgsg->get_numeric_type(numeric_type),
|
||||
stride, client_pointer + start);
|
||||
cgGLEnableClientState(p);
|
||||
}
|
||||
cgGLEnableClientState(p);
|
||||
} else {
|
||||
CGparameter p = _cg_parameter_map[_shader->_var_spec[i]._id._seqno];
|
||||
cgGLDisableClientState(p);
|
||||
@ -506,6 +527,7 @@ disable_shader_texture_bindings() {
|
||||
for (int i=0; i<(int)_shader->_tex_spec.size(); i++) {
|
||||
CGparameter p = _cg_parameter_map[_shader->_tex_spec[i]._id._seqno];
|
||||
if (p == 0) continue;
|
||||
|
||||
int texunit = cgGetParameterResourceIndex(p);
|
||||
_glgsg->_glActiveTexture(GL_TEXTURE0 + texunit);
|
||||
|
||||
@ -527,7 +549,7 @@ disable_shader_texture_bindings() {
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||
}
|
||||
// This is probably faster - but maybe not as safe?
|
||||
// cgGLDisableTextureParameter(p);
|
||||
//cgGLDisableTextureParameter(p);
|
||||
}
|
||||
#endif // OPENGLES_2
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Filename: glShaderContext_src.h
|
||||
// Filename: glCgShaderContext_src.h
|
||||
// Created by: jyelon (01Sep05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -51,15 +51,10 @@ public:
|
||||
INLINE bool uses_custom_texture_bindings(void);
|
||||
|
||||
private:
|
||||
CGcontext _cg_context;
|
||||
CGprogram _cg_vprogram;
|
||||
CGprogram _cg_fprogram;
|
||||
CGprogram _cg_gprogram;
|
||||
CGprofile _cg_vprofile;
|
||||
CGprofile _cg_fprofile;
|
||||
CGprofile _cg_gprofile;
|
||||
CGprogram _cg_program;
|
||||
bool _glsl_profile;
|
||||
|
||||
pvector <CGparameter> _cg_parameter_map;
|
||||
pvector<CGparameter> _cg_parameter_map;
|
||||
|
||||
CLP(GraphicsStateGuardian) *_glgsg;
|
||||
|
||||
|
@ -318,6 +318,10 @@ CLP(GraphicsStateGuardian)(GraphicsEngine *engine, GraphicsPipe *pipe) :
|
||||
_scissor_enabled = false;
|
||||
_scissor_attrib_active = false;
|
||||
|
||||
#ifdef HAVE_CG
|
||||
_cg_context = 0;
|
||||
#endif
|
||||
|
||||
#ifdef DO_PSTATS
|
||||
if (gl_finish) {
|
||||
GLCAT.warning()
|
||||
@ -1083,15 +1087,19 @@ reset() {
|
||||
_supports_depth_texture = true;
|
||||
}
|
||||
|
||||
if (_supports_depth_texture &&
|
||||
if (gl_support_shadow_filter &&
|
||||
_supports_depth_texture &&
|
||||
has_extension("GL_ARB_shadow") &&
|
||||
has_extension("GL_ARB_fragment_program_shadow")) {
|
||||
_supports_shadow_filter = true;
|
||||
}
|
||||
if (_gl_vendor.substr(0,3)=="ATI") {
|
||||
// Actually, we can't keep forever disabling ARB_shadow on ATI cards,
|
||||
// since they do work correctly now. Maybe there is some feature
|
||||
// level we can check somewhere?
|
||||
/*if (_gl_vendor.substr(0,3)=="ATI") {
|
||||
// ATI drivers have never provided correct shadow support.
|
||||
_supports_shadow_filter = false;
|
||||
}
|
||||
}*/
|
||||
|
||||
_supports_texture_combine =
|
||||
has_extension("GL_ARB_texture_env_combine") || is_at_least_gl_version(1, 3) || is_at_least_gles_version(1, 1);
|
||||
@ -1156,30 +1164,37 @@ reset() {
|
||||
|
||||
// cgGLGetLatestProfile doesn't seem to return anything other
|
||||
// arbvp1/arbfp1 on non-NVIDIA cards, which is severely limiting.
|
||||
// Actually, it seems that these profiles are horribly broken on these
|
||||
// cards. Let's not do this.
|
||||
//if ((_shader_caps._active_vprofile == CG_PROFILE_ARBVP1 ||
|
||||
// _shader_caps._active_fprofile == CG_PROFILE_ARBFP1) &&
|
||||
// cgGLIsProfileSupported(CG_PROFILE_GLSLV) &&
|
||||
// cgGLIsProfileSupported(CG_PROFILE_GLSLF)) {
|
||||
// So, if this happens, we set it to GLSL, which is
|
||||
// usually supported on all cards.
|
||||
// The GLSL profiles are horribly broken on non-NVIDIA cards, but
|
||||
// I think I've worked around the issues sufficiently.
|
||||
if ((_shader_caps._active_vprofile == CG_PROFILE_ARBVP1 ||
|
||||
_shader_caps._active_fprofile == CG_PROFILE_ARBFP1) &&
|
||||
cgGLIsProfileSupported(CG_PROFILE_GLSLV) &&
|
||||
cgGLIsProfileSupported(CG_PROFILE_GLSLF)) {
|
||||
|
||||
// // So, if this happens, we set it to GLSL, which is
|
||||
// // usually supported on all cards.
|
||||
// _shader_caps._active_vprofile = (int)CG_PROFILE_GLSLV;
|
||||
// _shader_caps._active_fprofile = (int)CG_PROFILE_GLSLF;
|
||||
_shader_caps._active_vprofile = (int)CG_PROFILE_GLSLV;
|
||||
_shader_caps._active_fprofile = (int)CG_PROFILE_GLSLF;
|
||||
#if CG_VERSION_NUM >= 2200
|
||||
// if (cgGLIsProfileSupported(CG_PROFILE_GLSLG)) {
|
||||
// _shader_caps._active_gprofile = (int)CG_PROFILE_GLSLG;
|
||||
// }
|
||||
if (cgGLIsProfileSupported(CG_PROFILE_GLSLG)) {
|
||||
_shader_caps._active_gprofile = (int)CG_PROFILE_GLSLG;
|
||||
}
|
||||
#endif
|
||||
//}
|
||||
}
|
||||
}
|
||||
_shader_caps._ultimate_vprofile = (int)CG_PROFILE_VP40;
|
||||
_shader_caps._ultimate_fprofile = (int)CG_PROFILE_FP40;
|
||||
_shader_caps._ultimate_gprofile = (int)CG_PROFILE_GPU_GP;
|
||||
|
||||
_glBindProgram = (PFNGLBINDPROGRAMARBPROC)
|
||||
get_extension_func("glBindProgramARB");
|
||||
_cg_context = cgCreateContext();
|
||||
|
||||
#if CG_VERSION_NUM >= 3100
|
||||
// This just sounds like a good thing to do.
|
||||
cgGLSetContextGLSLVersion(_cg_context, cgGLDetectGLSLVersion());
|
||||
if (_shader_caps._active_vprofile == CG_PROFILE_GLSLV) {
|
||||
cgGLSetContextOptimalOptions(_cg_context, CG_PROFILE_GLSLC);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Bug workaround for radeons.
|
||||
if (_shader_caps._active_fprofile == CG_PROFILE_ARBFP1) {
|
||||
@ -2244,9 +2259,17 @@ reset() {
|
||||
}
|
||||
#endif // CG_VERSION_NUM >= 2200
|
||||
|
||||
#if CG_VERSION_NUM >= 3100
|
||||
if (GLCAT.is_debug()) {
|
||||
CGGLglslversion ver = cgGLGetContextGLSLVersion(_cg_context);
|
||||
GLCAT.debug()
|
||||
<< "Cg GLSL version: " << cgGLGetGLSLVersionString(ver) << "\n";
|
||||
}
|
||||
#endif
|
||||
|
||||
GLCAT.debug()
|
||||
<< "\nCg vertex profile = " << cgGetProfileString(vertex_profile) << " id = " << vertex_profile
|
||||
<< "\nCg pixel profile = " << cgGetProfileString(pixel_profile) << " id = " << pixel_profile
|
||||
<< "\nCg latest vertex profile = " << cgGetProfileString(vertex_profile) << " id = " << vertex_profile
|
||||
<< "\nCg latest pixel profile = " << cgGetProfileString(pixel_profile) << " id = " << pixel_profile
|
||||
<< "\nshader model = " << _shader_model
|
||||
<< "\n";
|
||||
}
|
||||
@ -2591,6 +2614,7 @@ clear_before_callback() {
|
||||
// texture stage is still set to stage 0. CEGUI, in particular,
|
||||
// makes this assumption.
|
||||
_glActiveTexture(GL_TEXTURE0);
|
||||
_glClientActiveTexture(GL_TEXTURE0);
|
||||
|
||||
// Clear the bound sampler object, so that we do not inadvertently
|
||||
// override the callback's desired sampler settings.
|
||||
@ -9009,6 +9033,12 @@ set_state_and_transform(const RenderState *target,
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
free_pointers() {
|
||||
#ifdef HAVE_CG
|
||||
if (_cg_context != 0) {
|
||||
cgDestroyContext(_cg_context);
|
||||
_cg_context = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -568,6 +568,10 @@ protected:
|
||||
static PT(Shader) _default_shader;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CG
|
||||
CGcontext _cg_context;
|
||||
#endif
|
||||
|
||||
#ifdef SUPPORT_IMMEDIATE_MODE
|
||||
CLP(ImmediateModeSender) _sender;
|
||||
bool _use_sender;
|
||||
|
@ -265,6 +265,13 @@ ConfigVariableBool gl_support_sampler_objects
|
||||
"objects. Set to false if you suspect a bug in the "
|
||||
"driver implementation."));
|
||||
|
||||
ConfigVariableBool gl_support_shadow_filter
|
||||
("gl-support-shadow-filter", true,
|
||||
PRC_DESC("Disable this if you suspect a bug in the driver "
|
||||
"implementation of ARB_shadow. Particularly, older ATI "
|
||||
"cards suffered from a broken implementation of the "
|
||||
"shadow map filtering features."));
|
||||
|
||||
extern ConfigVariableBool gl_parallel_arrays;
|
||||
|
||||
void CLP(init_classes)() {
|
||||
|
@ -74,6 +74,7 @@ extern ConfigVariableBool gl_enable_memory_barriers;
|
||||
extern ConfigVariableBool gl_vertex_array_objects;
|
||||
extern ConfigVariableBool gl_support_primitive_restart_index;
|
||||
extern ConfigVariableBool gl_support_sampler_objects;
|
||||
extern ConfigVariableBool gl_support_shadow_filter;
|
||||
|
||||
extern EXPCL_GL void CLP(init_classes)();
|
||||
|
||||
|
@ -27,6 +27,7 @@ TypeHandle Shader::_type_handle;
|
||||
Shader::ShaderTable Shader::_load_table;
|
||||
Shader::ShaderTable Shader::_make_table;
|
||||
Shader::ShaderCaps Shader::_default_caps;
|
||||
CGcontext Shader::_cg_context = 0;
|
||||
int Shader::_shaders_generated;
|
||||
ShaderUtilization Shader::_shader_utilization = SUT_unspecified;
|
||||
|
||||
@ -480,46 +481,54 @@ cp_optimize_mat_spec(ShaderMatSpec &spec) {
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Shader::cg_recurse_parameters(CGparameter parameter,
|
||||
const ShaderType& type, bool& success) {
|
||||
void Shader::
|
||||
cg_recurse_parameters(CGparameter parameter, const ShaderType &type,
|
||||
bool &success) {
|
||||
|
||||
if (parameter == 0)
|
||||
if (parameter == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
do {
|
||||
int arg_dim[] = {1,0,0};
|
||||
ShaderArgDir arg_dir = cg_parameter_dir(parameter);
|
||||
ShaderArgType arg_type = cg_parameter_type(parameter);
|
||||
ShaderArgClass arg_class = cg_parameter_class(parameter);
|
||||
ShaderArgClass arg_subclass = arg_class;
|
||||
if (cgIsParameterReferenced(parameter)) {
|
||||
int arg_dim[] = {1,0,0};
|
||||
ShaderArgDir arg_dir = cg_parameter_dir(parameter);
|
||||
ShaderArgType arg_type = cg_parameter_type(parameter);
|
||||
ShaderArgClass arg_class = cg_parameter_class(parameter);
|
||||
ShaderArgClass arg_subclass = arg_class;
|
||||
|
||||
CGenum vbl = cgGetParameterVariability(parameter);
|
||||
CGenum vbl = cgGetParameterVariability(parameter);
|
||||
|
||||
if ((vbl==CG_VARYING)||(vbl==CG_UNIFORM)) {
|
||||
switch (cgGetParameterType(parameter)) {
|
||||
case CG_STRUCT:
|
||||
cg_recurse_parameters(
|
||||
cgGetFirstStructParameter(parameter), type, success);
|
||||
break;
|
||||
if ((vbl==CG_VARYING)||(vbl==CG_UNIFORM)) {
|
||||
switch (cgGetParameterType(parameter)) {
|
||||
case CG_STRUCT:
|
||||
cg_recurse_parameters(
|
||||
cgGetFirstStructParameter(parameter), type, success);
|
||||
break;
|
||||
|
||||
case CG_ARRAY:
|
||||
arg_type = cg_parameter_type(cgGetArrayParameter(parameter, 0));
|
||||
arg_subclass = cg_parameter_class(cgGetArrayParameter(parameter, 0));
|
||||
case CG_ARRAY:
|
||||
arg_type = cg_parameter_type(cgGetArrayParameter(parameter, 0));
|
||||
arg_subclass = cg_parameter_class(cgGetArrayParameter(parameter, 0));
|
||||
|
||||
arg_dim[0] = cgGetArraySize(parameter, 0);
|
||||
arg_dim[0] = cgGetArraySize(parameter, 0);
|
||||
|
||||
default: {
|
||||
arg_dim[1] = cgGetParameterRows(parameter);
|
||||
arg_dim[2] = cgGetParameterColumns(parameter);
|
||||
default: {
|
||||
arg_dim[1] = cgGetParameterRows(parameter);
|
||||
arg_dim[2] = cgGetParameterColumns(parameter);
|
||||
|
||||
ShaderArgId id;
|
||||
id._name = cgGetParameterName(parameter);
|
||||
id._type = type;
|
||||
id._seqno = -1;
|
||||
success &= compile_parameter(id, arg_class, arg_subclass, arg_type,
|
||||
arg_dir, (vbl == CG_VARYING), arg_dim, gobj_cat.get_safe_ptr()); break;
|
||||
ShaderArgId id;
|
||||
id._name = cgGetParameterName(parameter);
|
||||
id._type = type;
|
||||
id._seqno = -1;
|
||||
success &= compile_parameter(id, arg_class, arg_subclass, arg_type,
|
||||
arg_dir, (vbl == CG_VARYING), arg_dim, gobj_cat.get_safe_ptr()); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (gobj_cat.is_debug()) {
|
||||
gobj_cat.debug()
|
||||
<< "Parameter " << cgGetParameterName(parameter)
|
||||
<< " is unreferenced within shader " << get_filename(type) << "\n";
|
||||
}
|
||||
} while((parameter = cgGetNextParameter(parameter))!= 0);
|
||||
}
|
||||
@ -1375,10 +1384,6 @@ cg_release_resources() {
|
||||
cgDestroyProgram(_cg_gprogram);
|
||||
_cg_gprogram = 0;
|
||||
}
|
||||
if (_cg_context != 0) {
|
||||
cgDestroyContext(_cg_context);
|
||||
_cg_context = 0;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -1387,7 +1392,8 @@ cg_release_resources() {
|
||||
// Description: xyz
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CGprogram Shader::
|
||||
cg_compile_entry_point(const char *entry, const ShaderCaps &caps, ShaderType type) {
|
||||
cg_compile_entry_point(const char *entry, const ShaderCaps &caps,
|
||||
CGcontext context, ShaderType type) {
|
||||
CGprogram prog;
|
||||
CGerror err;
|
||||
const char *compiler_args[100];
|
||||
@ -1457,7 +1463,7 @@ cg_compile_entry_point(const char *entry, const ShaderCaps &caps, ShaderType typ
|
||||
}
|
||||
|
||||
// Compile the shader with the active profile.
|
||||
prog = cgCreateProgram(_cg_context, CG_SOURCE, text.c_str(),
|
||||
prog = cgCreateProgram(context, CG_SOURCE, text.c_str(),
|
||||
(CGprofile)active, entry, (const char **)compiler_args);
|
||||
err = cgGetError();
|
||||
if (err == CG_NO_ERROR) {
|
||||
@ -1479,30 +1485,35 @@ cg_compile_entry_point(const char *entry, const ShaderCaps &caps, ShaderType typ
|
||||
}
|
||||
|
||||
// The active profile failed, so recompile it with the ultimate profile.
|
||||
prog = cgCreateProgram(_cg_context, CG_SOURCE, text.c_str(),
|
||||
prog = cgCreateProgram(context, CG_SOURCE, text.c_str(),
|
||||
(CGprofile)ultimate, entry, (const char **)NULL);
|
||||
|
||||
// Extract the output listing.
|
||||
err = cgGetError();
|
||||
const char *listing = cgGetLastListing(context);
|
||||
|
||||
if (err == CG_NO_ERROR && listing != NULL && strlen(listing) > 1) {
|
||||
gobj_cat.warning()
|
||||
<< "Encountered warnings during compilation of " << get_filename(type)
|
||||
<< ":\n" << listing;
|
||||
|
||||
} else if (err == CG_COMPILER_ERROR) {
|
||||
gobj_cat.error()
|
||||
<< "Failed to compile Cg shader " << get_filename(type);
|
||||
if (listing != NULL) {
|
||||
gobj_cat.error(false) << ":\n" << listing;
|
||||
} else {
|
||||
gobj_cat.error(false) << "!\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (err == CG_NO_ERROR) {
|
||||
return prog;
|
||||
}
|
||||
if (err == CG_COMPILER_ERROR) {
|
||||
// A compiler error has occurred. Extract the error messages.
|
||||
string listing = cgGetLastListing(_cg_context);
|
||||
vector_string errlines;
|
||||
tokenize(listing, errlines, "\n");
|
||||
for (int i = 0; i < (int) errlines.size(); ++i) {
|
||||
string line = trim(errlines[i]);
|
||||
if (line != "") {
|
||||
gobj_cat.error() << get_filename(type) << ": " << errlines[i] << "\n";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
gobj_cat.error() << get_filename(type) << ": " << cgGetErrorString(err) << "\n";
|
||||
}
|
||||
|
||||
if (prog != 0) {
|
||||
cgDestroyProgram(prog);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1514,29 +1525,11 @@ cg_compile_entry_point(const char *entry, const ShaderCaps &caps, ShaderType typ
|
||||
// variables _cg_context, _cg_vprogram, _cg_fprogram.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool Shader::
|
||||
cg_compile_shader(const ShaderCaps &caps) {
|
||||
|
||||
// If we already tried compiling for this set of caps, there's no point
|
||||
// trying again. Just return the results of the previous compile.
|
||||
if (caps == _cg_last_caps) {
|
||||
if (_cg_context == 0) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
cg_compile_shader(const ShaderCaps &caps, CGcontext context) {
|
||||
_cg_last_caps = caps;
|
||||
|
||||
_cg_context = cgCreateContext();
|
||||
|
||||
if (_cg_context == 0) {
|
||||
gobj_cat.error() << "Could not create a Cg context object.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_text._separate || !_text._vertex.empty()) {
|
||||
_cg_vprogram = cg_compile_entry_point("vshader", caps, ST_vertex);
|
||||
_cg_vprogram = cg_compile_entry_point("vshader", caps, context, ST_vertex);
|
||||
if (_cg_vprogram == 0) {
|
||||
cg_release_resources();
|
||||
return false;
|
||||
@ -1545,7 +1538,7 @@ cg_compile_shader(const ShaderCaps &caps) {
|
||||
}
|
||||
|
||||
if (!_text._separate || !_text._fragment.empty()) {
|
||||
_cg_fprogram = cg_compile_entry_point("fshader", caps, ST_fragment);
|
||||
_cg_fprogram = cg_compile_entry_point("fshader", caps, context, ST_fragment);
|
||||
if (_cg_fprogram == 0) {
|
||||
cg_release_resources();
|
||||
return false;
|
||||
@ -1554,7 +1547,7 @@ cg_compile_shader(const ShaderCaps &caps) {
|
||||
}
|
||||
|
||||
if ((_text._separate && !_text._geometry.empty()) || (!_text._separate && _text._shared.find("gshader") != string::npos)) {
|
||||
_cg_gprogram = cg_compile_entry_point("gshader", caps, ST_geometry);
|
||||
_cg_gprogram = cg_compile_entry_point("gshader", caps, context, ST_geometry);
|
||||
if (_cg_gprogram == 0) {
|
||||
cg_release_resources();
|
||||
return false;
|
||||
@ -1606,7 +1599,7 @@ bool Shader::
|
||||
cg_analyze_entry_point(CGprogram prog, ShaderType type) {
|
||||
bool success = true;
|
||||
|
||||
cg_recurse_parameters(cgGetFirstParameter(prog, CG_PROGRAM),type,success);
|
||||
cg_recurse_parameters(cgGetFirstParameter(prog, CG_PROGRAM), type, success);
|
||||
return success;
|
||||
}
|
||||
|
||||
@ -1645,7 +1638,18 @@ cg_analyze_entry_point(CGprogram prog, ShaderType type) {
|
||||
bool Shader::
|
||||
cg_analyze_shader(const ShaderCaps &caps) {
|
||||
|
||||
if (!cg_compile_shader(caps)) {
|
||||
// Make sure we have a context for analyzing the shader.
|
||||
if (_cg_context == 0) {
|
||||
_cg_context = cgCreateContext();
|
||||
if (_cg_context == 0) {
|
||||
gobj_cat.error()
|
||||
<< "Could not create a Cg context object: "
|
||||
<< cgGetErrorString(cgGetError()) << "\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!cg_compile_shader(caps, _cg_context)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1805,26 +1809,18 @@ cg_program_from_shadertype(ShaderType type) {
|
||||
// longer own them.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool Shader::
|
||||
cg_compile_for(const ShaderCaps &caps,
|
||||
CGcontext &ctx,
|
||||
CGprogram &vprogram,
|
||||
CGprogram &fprogram,
|
||||
CGprogram &gprogram,
|
||||
pvector<CGparameter> &map) {
|
||||
cg_compile_for(const ShaderCaps &caps, CGcontext context,
|
||||
CGprogram &combined_program, pvector<CGparameter> &map) {
|
||||
|
||||
// Initialize the return values to empty.
|
||||
ctx = 0;
|
||||
vprogram = 0;
|
||||
fprogram = 0;
|
||||
gprogram = 0;
|
||||
|
||||
combined_program = 0;
|
||||
map.clear();
|
||||
|
||||
// Make sure the shader is compiled for the target caps.
|
||||
// Most of the time, it will already be - this is usually a no-op.
|
||||
|
||||
_default_caps = caps;
|
||||
if (!cg_compile_shader(caps)) {
|
||||
if (!cg_compile_shader(caps, context)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1850,8 +1846,24 @@ cg_compile_for(const ShaderCaps &caps,
|
||||
return false;
|
||||
}
|
||||
|
||||
// Build a parameter map.
|
||||
// Gather the programs we will be combining.
|
||||
pvector<CGprogram> programs;
|
||||
if (_cg_vprogram != 0) {
|
||||
programs.push_back(_cg_vprogram);
|
||||
}
|
||||
if (_cg_fprogram != 0) {
|
||||
programs.push_back(_cg_fprogram);
|
||||
}
|
||||
if (_cg_gprogram != 0) {
|
||||
programs.push_back(_cg_gprogram);
|
||||
}
|
||||
|
||||
// Combine the programs. This can be more optimal than loading them
|
||||
// individually, and it is even necessary for some profiles
|
||||
// (particularly GLSL profiles on non-NVIDIA GPUs).
|
||||
combined_program = cgCombinePrograms(programs.size(), &programs[0]);
|
||||
|
||||
// Build a parameter map.
|
||||
int n_mat = (int)_mat_spec.size();
|
||||
int n_tex = (int)_tex_spec.size();
|
||||
int n_var = (int)_var_spec.size();
|
||||
@ -1859,46 +1871,103 @@ cg_compile_for(const ShaderCaps &caps,
|
||||
|
||||
map.resize(n_mat + n_tex + n_var + n_ptr);
|
||||
|
||||
for (int i=0; i<n_mat; i++) {
|
||||
// This is a bit awkward, we have to go in and seperate out the
|
||||
// combined program, since all the parameter bindings have changed.
|
||||
CGprogram programs_by_type[ST_COUNT];
|
||||
for (int i = 0; i < cgGetNumProgramDomains(combined_program); ++i) {
|
||||
// Conveniently, the CGdomain enum overlaps with ShaderType.
|
||||
CGprogram program = cgGetProgramDomainProgram(combined_program, i);
|
||||
programs_by_type[cgGetProgramDomain(program)] = program;
|
||||
}
|
||||
|
||||
for (int i = 0; i < n_mat; ++i) {
|
||||
const ShaderArgId &id = _mat_spec[i]._id;
|
||||
|
||||
CGprogram prog = cg_program_from_shadertype(id._type); // CG2 CHANGE
|
||||
map[id._seqno] = cgGetNamedParameter(prog, id._name.c_str());
|
||||
map[id._seqno] = cgGetNamedParameter(programs_by_type[id._type], id._name.c_str());
|
||||
}
|
||||
for (int i=0; i<n_tex; i++) {
|
||||
|
||||
for (int i = 0; i < n_tex; ++i) {
|
||||
const ShaderArgId &id = _tex_spec[i]._id;
|
||||
CGprogram prog = cg_program_from_shadertype(id._type); // CG2 CHANGE
|
||||
map[id._seqno] = cgGetNamedParameter(prog, id._name.c_str());
|
||||
if (cgGetParameterBaseResource(map[id._seqno]) == CG_UNDEFINED) {
|
||||
map[id._seqno] = 0;
|
||||
CGparameter p = cgGetNamedParameter(programs_by_type[id._type], id._name.c_str());
|
||||
|
||||
if (gobj_cat.is_debug()) {
|
||||
const char *resource = cgGetParameterResourceName(p);
|
||||
if (resource != NULL) {
|
||||
gobj_cat.debug() << "Texture parameter " << id._name
|
||||
<< " is bound to resource " << resource << "\n";
|
||||
}
|
||||
}
|
||||
map[id._seqno] = p;
|
||||
}
|
||||
for (int i=0; i<n_var; i++) {
|
||||
|
||||
for (int i = 0; i < n_var; ++i) {
|
||||
const ShaderArgId &id = _var_spec[i]._id;
|
||||
CGparameter p = cgGetNamedParameter(programs_by_type[id._type], id._name.c_str());
|
||||
|
||||
CGprogram prog = cg_program_from_shadertype(id._type); // CG2 CHANGE
|
||||
map[id._seqno] = cgGetNamedParameter(prog, id._name.c_str());
|
||||
if (cgGetParameterBaseResource(map[id._seqno]) == CG_UNDEFINED) {
|
||||
map[id._seqno] = 0;
|
||||
const char *resource = cgGetParameterResourceName(p);
|
||||
if (gobj_cat.is_debug() && resource != NULL) {
|
||||
gobj_cat.debug()
|
||||
<< "Varying parameter " << id._name << " is bound to resource "
|
||||
<< cgGetParameterResourceName(p) << "\n";
|
||||
}
|
||||
}
|
||||
for (int i=0; i<n_ptr; i++) {
|
||||
const ShaderArgId &id = _ptr_spec[i]._id;
|
||||
|
||||
CGprogram prog = cg_program_from_shadertype(id._type); // CG2 CHANGE
|
||||
map[id._seqno] = cgGetNamedParameter(prog, id._name.c_str());
|
||||
if (cgGetParameterBaseResource(p) == CG_UNDEFINED) {
|
||||
// I really don't know what this means, but it happens when I
|
||||
// use the NORMAL0 semantic instead of NORMAL, or POSITION0
|
||||
// instead of POSITION, etc. Not catching this results in a
|
||||
// continuous stream of errors at the renderer side.
|
||||
gobj_cat.error()
|
||||
<< "Varying parameter " << id._name;
|
||||
|
||||
const char *semantic = cgGetParameterSemantic(p);
|
||||
if (semantic != NULL) {
|
||||
gobj_cat.error(false) << " : " << semantic;
|
||||
}
|
||||
if (resource != NULL) {
|
||||
gobj_cat.error(false) << " (bound to resource " << resource << ")";
|
||||
}
|
||||
gobj_cat.error(false) << " is invalid!\n";
|
||||
|
||||
#ifndef NDEBUG
|
||||
// Let's try to give the developer a hint...
|
||||
if (semantic != NULL) {
|
||||
if (strcmp(semantic, "POSITION0") == 0) {
|
||||
gobj_cat.error() << "Try using the semantic POSITION instead of POSITION0.\n";
|
||||
} else if (strcmp(semantic, "NORMAL0") == 0) {
|
||||
gobj_cat.error() << "Try using the semantic NORMAL instead of NORMAL0.\n";
|
||||
} else if (strcmp(semantic, "DIFFUSE0") == 0) {
|
||||
gobj_cat.error() << "Try using the semantic DIFFUSE instead of DIFFUSE0.\n";
|
||||
} else if (strcmp(semantic, "SPECULAR0") == 0) {
|
||||
gobj_cat.error() << "Try using the semantic SPECULAR instead of SPECULAR0.\n";
|
||||
} else if (strcmp(semantic, "FOGCOORD0") == 0) {
|
||||
gobj_cat.error() << "Try using the semantic FOGCOORD instead of FOGCOORD0.\n";
|
||||
} else if (strcmp(semantic, "PSIZE0") == 0) {
|
||||
gobj_cat.error() << "Try using the semantic PSIZE instead of PSIZE0.\n";
|
||||
}
|
||||
}
|
||||
#endif // NDEBUG
|
||||
p = 0;
|
||||
}
|
||||
map[id._seqno] = p;
|
||||
}
|
||||
|
||||
for (int i = 0; i < n_ptr; ++i) {
|
||||
const ShaderArgId &id = _ptr_spec[i]._id;
|
||||
map[id._seqno] = cgGetNamedParameter(programs_by_type[id._type], id._name.c_str());
|
||||
}
|
||||
|
||||
// Transfer ownership of the compiled shader.
|
||||
ctx = _cg_context;
|
||||
vprogram = _cg_vprogram;
|
||||
fprogram = _cg_fprogram;
|
||||
gprogram = _cg_gprogram;
|
||||
|
||||
_cg_context = 0;
|
||||
_cg_vprogram = 0;
|
||||
_cg_fprogram = 0;
|
||||
_cg_gprogram = 0;
|
||||
if (_cg_vprogram != 0) {
|
||||
cgDestroyProgram(_cg_vprogram);
|
||||
_cg_vprogram = 0;
|
||||
}
|
||||
if (_cg_fprogram != 0) {
|
||||
cgDestroyProgram(_cg_fprogram);
|
||||
_cg_fprogram = 0;
|
||||
}
|
||||
if (_cg_gprogram != 0) {
|
||||
cgDestroyProgram(_cg_gprogram);
|
||||
_cg_gprogram = 0;
|
||||
}
|
||||
|
||||
_cg_last_caps.clear();
|
||||
|
||||
@ -1921,7 +1990,6 @@ Shader(ShaderLanguage lang) :
|
||||
_last_modified(0)
|
||||
{
|
||||
#ifdef HAVE_CG
|
||||
_cg_context = 0;
|
||||
_cg_vprogram = 0;
|
||||
_cg_fprogram = 0;
|
||||
_cg_gprogram = 0;
|
||||
@ -2006,9 +2074,7 @@ read(const ShaderFile &sfile) {
|
||||
// Determine which language the shader is written in.
|
||||
if (_language == SL_Cg) {
|
||||
#ifdef HAVE_CG
|
||||
if (!_text._separate) {
|
||||
cg_get_profile_from_header(_default_caps);
|
||||
}
|
||||
cg_get_profile_from_header(_default_caps);
|
||||
|
||||
if (!cg_analyze_shader(_default_caps)) {
|
||||
gobj_cat.error()
|
||||
|
@ -63,6 +63,7 @@ PUBLISHED:
|
||||
ST_tess_control,
|
||||
ST_tess_evaluation,
|
||||
ST_compute,
|
||||
ST_COUNT
|
||||
};
|
||||
|
||||
enum AutoShaderSwitch {
|
||||
@ -472,12 +473,13 @@ private:
|
||||
ShaderArgType cg_parameter_type(CGparameter p);
|
||||
ShaderArgDir cg_parameter_dir(CGparameter p);
|
||||
|
||||
CGprogram cg_compile_entry_point(const char *entry, const ShaderCaps &caps, ShaderType type = ST_vertex);
|
||||
CGprogram cg_compile_entry_point(const char *entry, const ShaderCaps &caps,
|
||||
CGcontext context, ShaderType type);
|
||||
|
||||
bool cg_analyze_entry_point(CGprogram prog, ShaderType type);
|
||||
|
||||
bool cg_analyze_shader(const ShaderCaps &caps);
|
||||
bool cg_compile_shader(const ShaderCaps &caps);
|
||||
bool cg_compile_shader(const ShaderCaps &caps, CGcontext context);
|
||||
void cg_release_resources();
|
||||
void cg_report_errors();
|
||||
|
||||
@ -486,7 +488,7 @@ private:
|
||||
void cg_get_profile_from_header(ShaderCaps &caps);
|
||||
|
||||
ShaderCaps _cg_last_caps;
|
||||
CGcontext _cg_context;
|
||||
static CGcontext _cg_context;
|
||||
CGprogram _cg_vprogram;
|
||||
CGprogram _cg_fprogram;
|
||||
CGprogram _cg_gprogram;
|
||||
@ -498,9 +500,8 @@ private:
|
||||
CGprogram cg_program_from_shadertype(ShaderType type);
|
||||
|
||||
public:
|
||||
bool cg_compile_for(const ShaderCaps &caps, CGcontext &ctx,
|
||||
CGprogram &vprogram, CGprogram &fprogram,
|
||||
CGprogram &gprogram, pvector<CGparameter> &map);
|
||||
bool cg_compile_for(const ShaderCaps &caps, CGcontext context,
|
||||
CGprogram &combined_program, pvector<CGparameter> &map);
|
||||
|
||||
#endif
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user