mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 08:44:19 -04:00
Cg fixes for DX9
This commit is contained in:
parent
fa7730819f
commit
c34758ea5c
@ -23,6 +23,7 @@ This issue fixes several bugs that were still found in 1.9.2.
|
|||||||
* Fix compile error when making static build with DX9 renderer
|
* Fix compile error when making static build with DX9 renderer
|
||||||
* Fix assertion when using aux render targets in DX9
|
* Fix assertion when using aux render targets in DX9
|
||||||
* Work around Cg bug generating invalid ASM for saturated tex loads
|
* Work around Cg bug generating invalid ASM for saturated tex loads
|
||||||
|
* Fix issues with certain Cg shader inputs in DX9
|
||||||
|
|
||||||
------------------------ RELEASE 1.9.2 ------------------------
|
------------------------ RELEASE 1.9.2 ------------------------
|
||||||
|
|
||||||
|
@ -431,10 +431,35 @@ extract_texture_data(Texture *tex) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
ShaderContext *DXGraphicsStateGuardian9::
|
ShaderContext *DXGraphicsStateGuardian9::
|
||||||
prepare_shader(Shader *se) {
|
prepare_shader(Shader *se) {
|
||||||
|
PStatTimer timer(_prepare_shader_pcollector);
|
||||||
|
|
||||||
|
switch (se->get_language()) {
|
||||||
|
case Shader::SL_GLSL:
|
||||||
|
dxgsg9_cat.error()
|
||||||
|
<< "Tried to load GLSL shader, but GLSL shaders not supported by Direct3D 9.\n";
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
case Shader::SL_Cg:
|
||||||
#ifdef HAVE_CG
|
#ifdef HAVE_CG
|
||||||
CLP(ShaderContext) *result = new CLP(ShaderContext)(se, this);
|
if (_supports_basic_shaders) {
|
||||||
return result;
|
return new CLP(ShaderContext)(se, this);
|
||||||
|
} else {
|
||||||
|
dxgsg9_cat.error()
|
||||||
|
<< "Tried to load Cg shader, but basic shaders not supported.\n";
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
dxgsg9_cat.error()
|
||||||
|
<< "Tried to load Cg shader, but Cg support not compiled in.\n";
|
||||||
|
return NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
default:
|
||||||
|
dxgsg9_cat.error()
|
||||||
|
<< "Tried to load shader with unsupported shader language!\n";
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +49,6 @@ CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
|
|||||||
CGcontext context = DCAST(DXGraphicsStateGuardian9, gsg)->_cg_context;
|
CGcontext context = DCAST(DXGraphicsStateGuardian9, gsg)->_cg_context;
|
||||||
|
|
||||||
if (s->get_language() == Shader::SL_Cg) {
|
if (s->get_language() == Shader::SL_Cg) {
|
||||||
|
|
||||||
// Ask the shader to compile itself for us and
|
// Ask the shader to compile itself for us and
|
||||||
// to give us the resulting Cg program objects.
|
// to give us the resulting Cg program objects.
|
||||||
if (!s->cg_compile_for(gsg->_shader_caps, context,
|
if (!s->cg_compile_for(gsg->_shader_caps, context,
|
||||||
@ -259,43 +258,54 @@ issue_parameters(GSG *gsg, int altered) {
|
|||||||
#ifdef HAVE_CG
|
#ifdef HAVE_CG
|
||||||
if (_cg_program) {
|
if (_cg_program) {
|
||||||
|
|
||||||
// Iterate through _ptr parameters
|
// Iterate through _ptr parameters
|
||||||
for (int i=0; i<(int)_shader->_ptr_spec.size(); i++) {
|
for (size_t i = 0; i < _shader->_ptr_spec.size(); ++i) {
|
||||||
if(altered & (_shader->_ptr_spec[i]._dep[0] | _shader->_ptr_spec[i]._dep[1])){
|
const Shader::ShaderPtrSpec &spec = _shader->_ptr_spec[i];
|
||||||
#ifdef HAVE_CG
|
|
||||||
const Shader::ShaderPtrSpec& _ptr = _shader->_ptr_spec[i];
|
|
||||||
Shader::ShaderPtrData* _ptr_data =
|
|
||||||
const_cast< Shader::ShaderPtrData*>(gsg->fetch_ptr_parameter(_ptr));
|
|
||||||
|
|
||||||
if (_ptr_data == NULL){ //the input is not contained in ShaderPtrData
|
if (altered & (spec._dep[0] | spec._dep[1])) {
|
||||||
|
const Shader::ShaderPtrData *ptr_data = gsg->fetch_ptr_parameter(spec);
|
||||||
|
|
||||||
|
if (ptr_data == NULL) { //the input is not contained in ShaderPtrData
|
||||||
release_resources();
|
release_resources();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGparameter p = _cg_parameter_map[_ptr._id._seqno];
|
// Calculate how many elements to transfer; no more than it expects,
|
||||||
|
// but certainly no more than we have.
|
||||||
|
int input_size = min(abs(spec._dim[0] * spec._dim[1] * spec._dim[2]), ptr_data->_size);
|
||||||
|
|
||||||
|
CGparameter p = _cg_parameter_map[spec._id._seqno];
|
||||||
|
switch (ptr_data->_type) {
|
||||||
|
case Shader::SPT_int:
|
||||||
|
cgSetParameterValueic(p, input_size, (int *)ptr_data->_ptr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Shader::SPT_double:
|
||||||
|
cgSetParameterValuedc(p, input_size, (double *)ptr_data->_ptr);
|
||||||
|
break;
|
||||||
|
|
||||||
switch(_ptr_data->_type) {
|
|
||||||
case Shader::SPT_float:
|
case Shader::SPT_float:
|
||||||
cgD3D9SetUniform(p, (PN_stdfloat*)_ptr_data->_ptr);
|
cgSetParameterValuefc(p, input_size, (float *)ptr_data->_ptr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
dxgsg9_cat.error()
|
dxgsg9_cat.error()
|
||||||
<< _ptr._id._name << ":" << "unrecognized parameter type\n";
|
<< spec._id._name << ": unrecognized parameter type\n";
|
||||||
release_resources();
|
release_resources();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0; i<(int)_shader->_mat_spec.size(); i++) {
|
for (size_t i = 0; i < _shader->_mat_spec.size(); ++i) {
|
||||||
if (altered & (_shader->_mat_spec[i]._dep[0] | _shader->_mat_spec[i]._dep[1])) {
|
Shader::ShaderMatSpec &spec = _shader->_mat_spec[i];
|
||||||
CGparameter p = _cg_parameter_map[_shader->_mat_spec[i]._id._seqno];
|
|
||||||
|
if (altered & (spec._dep[0] | spec._dep[1])) {
|
||||||
|
CGparameter p = _cg_parameter_map[spec._id._seqno];
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const LMatrix4 *val = gsg->fetch_specified_value(_shader->_mat_spec[i], altered);
|
const LMatrix4 *val = gsg->fetch_specified_value(spec, altered);
|
||||||
if (val) {
|
if (val) {
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
PN_stdfloat v [4];
|
PN_stdfloat v [4];
|
||||||
@ -309,12 +319,12 @@ issue_parameters(GSG *gsg, int altered) {
|
|||||||
#if DEBUG_SHADER
|
#if DEBUG_SHADER
|
||||||
// DEBUG
|
// DEBUG
|
||||||
global_data = (PN_stdfloat *) data;
|
global_data = (PN_stdfloat *) data;
|
||||||
global_shader_mat_spec = &_shader->_mat_spec[i];
|
global_shader_mat_spec = &spec;
|
||||||
global_internal_name_0 = global_shader_mat_spec -> _arg [0];
|
global_internal_name_0 = global_shader_mat_spec -> _arg [0];
|
||||||
global_internal_name_1 = global_shader_mat_spec -> _arg [1];
|
global_internal_name_1 = global_shader_mat_spec -> _arg [1];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
switch (_shader->_mat_spec[i]._piece) {
|
switch (spec._piece) {
|
||||||
case Shader::SMP_whole:
|
case Shader::SMP_whole:
|
||||||
// TRANSPOSE REQUIRED
|
// TRANSPOSE REQUIRED
|
||||||
temp_matrix.transpose_in_place();
|
temp_matrix.transpose_in_place();
|
||||||
@ -363,26 +373,22 @@ issue_parameters(GSG *gsg, int altered) {
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
dxgsg9_cat.error()
|
dxgsg9_cat.error()
|
||||||
<< "issue_parameters ( ) SMP parameter type not implemented " << _shader->_mat_spec[i]._piece << "\n";
|
<< "issue_parameters ( ) SMP parameter type not implemented " << spec._piece << "\n";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FAILED (hr)) {
|
if (FAILED (hr)) {
|
||||||
|
|
||||||
string name = "unnamed";
|
string name = "unnamed";
|
||||||
|
|
||||||
if (_shader->_mat_spec[i]._arg [0]) {
|
if (spec._arg[0]) {
|
||||||
name = _shader->_mat_spec[i]._arg [0] -> get_basename ( );
|
name = spec._arg[0]->get_basename();
|
||||||
}
|
}
|
||||||
|
|
||||||
dxgsg9_cat.error()
|
dxgsg9_cat.error()
|
||||||
<< "NAME " << name << "\n"
|
<< "NAME " << name << "\n" << "MAT TYPE " << spec._piece
|
||||||
<< "MAT TYPE "
|
<< " cgD3D9SetUniform failed " << D3DERRORSTRING(hr);
|
||||||
<< _shader->_mat_spec[i]._piece
|
|
||||||
<< " cgD3D9SetUniform failed "
|
|
||||||
<< D3DERRORSTRING(hr);
|
|
||||||
|
|
||||||
CGerror error = cgGetError ();
|
CGerror error = cgGetError();
|
||||||
if (error != CG_NO_ERROR) {
|
if (error != CG_NO_ERROR) {
|
||||||
dxgsg9_cat.error() << " CG ERROR: " << cgGetErrorString(error) << "\n";
|
dxgsg9_cat.error() << " CG ERROR: " << cgGetErrorString(error) << "\n";
|
||||||
}
|
}
|
||||||
@ -713,25 +719,26 @@ disable_shader_texture_bindings(GSG *gsg)
|
|||||||
// reenable them. We may optimize this someday.
|
// reenable them. We may optimize this someday.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void CLP(ShaderContext)::
|
void CLP(ShaderContext)::
|
||||||
update_shader_texture_bindings(CLP(ShaderContext) *prev, GSG *gsg)
|
update_shader_texture_bindings(CLP(ShaderContext) *prev, GSG *gsg) {
|
||||||
{
|
if (prev) {
|
||||||
if (prev) prev->disable_shader_texture_bindings(gsg);
|
prev->disable_shader_texture_bindings(gsg);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef HAVE_CG
|
#ifdef HAVE_CG
|
||||||
if (_cg_program) {
|
if (_cg_program) {
|
||||||
|
for (size_t i = 0; i < _shader->_tex_spec.size(); ++i) {
|
||||||
for (int i=0; i<(int)_shader->_tex_spec.size(); i++) {
|
const Shader::ShaderTexSpec &spec = _shader->_tex_spec[i];
|
||||||
CGparameter p = _cg_parameter_map[_shader->_tex_spec[i]._id._seqno];
|
CGparameter p = _cg_parameter_map[spec._id._seqno];
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture *tex = NULL;
|
Texture *tex = NULL;
|
||||||
int view = gsg->get_current_tex_view_offset();
|
int view = gsg->get_current_tex_view_offset();
|
||||||
InternalName *id = _shader->_tex_spec[i]._name;
|
|
||||||
SamplerState sampler;
|
SamplerState sampler;
|
||||||
|
|
||||||
if (id != NULL) {
|
if (spec._name != NULL) {
|
||||||
const ShaderInput *input = gsg->_target_shader->get_shader_input(id);
|
const ShaderInput *input = gsg->_target_shader->get_shader_input(spec._name);
|
||||||
tex = input->get_texture();
|
tex = input->get_texture();
|
||||||
sampler = input->get_sampler();
|
sampler = input->get_sampler();
|
||||||
|
|
||||||
@ -741,31 +748,33 @@ update_shader_texture_bindings(CLP(ShaderContext) *prev, GSG *gsg)
|
|||||||
const TextureAttrib *texattrib = DCAST(TextureAttrib, gsg->_target_rs->get_attrib_def(TextureAttrib::get_class_slot()));
|
const TextureAttrib *texattrib = DCAST(TextureAttrib, gsg->_target_rs->get_attrib_def(TextureAttrib::get_class_slot()));
|
||||||
nassertv(texattrib != (TextureAttrib *)NULL);
|
nassertv(texattrib != (TextureAttrib *)NULL);
|
||||||
|
|
||||||
if (_shader->_tex_spec[i]._stage >= texattrib->get_num_on_stages()) {
|
if (spec._stage >= texattrib->get_num_on_stages()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
TextureStage *stage = texattrib->get_on_stage(_shader->_tex_spec[i]._stage);
|
TextureStage *stage = texattrib->get_on_stage(spec._stage);
|
||||||
tex = texattrib->get_on_texture(stage);
|
tex = texattrib->get_on_texture(stage);
|
||||||
sampler = texattrib->get_on_sampler(stage);
|
sampler = texattrib->get_on_sampler(stage);
|
||||||
view += stage->get_tex_view_offset();
|
view += stage->get_tex_view_offset();
|
||||||
}
|
}
|
||||||
if (_shader->_tex_spec[i]._suffix != 0) {
|
|
||||||
// The suffix feature is inefficient. It is a temporary hack.
|
if (spec._suffix != 0) {
|
||||||
|
// The suffix feature is inefficient. It is a temporary hack.
|
||||||
if (tex == 0) {
|
if (tex == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
tex = tex->load_related(_shader->_tex_spec[i]._suffix);
|
tex = tex->load_related(spec._suffix);
|
||||||
}
|
}
|
||||||
if ((tex == 0) || (tex->get_texture_type() != _shader->_tex_spec[i]._desired_type)) {
|
|
||||||
|
if ((tex == 0) || (tex->get_texture_type() != spec._desired_type)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureContext *tc = tex->prepare_now(view, gsg->_prepared_objects, gsg);
|
TextureContext *tc = tex->prepare_now(view, gsg->_prepared_objects, gsg);
|
||||||
if (tc == (TextureContext*)NULL) {
|
if (tc == (TextureContext*)NULL) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int texunit = cgGetParameterResourceIndex(p);
|
int texunit = cgGetParameterResourceIndex(p);
|
||||||
|
|
||||||
gsg->apply_texture(texunit, tc, sampler);
|
gsg->apply_texture(texunit, tc, sampler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -688,9 +688,15 @@ get_ptr() const {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE const SamplerState &ShaderInput::
|
INLINE const SamplerState &ShaderInput::
|
||||||
get_sampler() const {
|
get_sampler() const {
|
||||||
return (_type == M_texture)
|
if (_type != M_texture) {
|
||||||
? get_texture()->get_default_sampler()
|
return _sampler;
|
||||||
: _sampler;
|
|
||||||
|
} else if (!_value.is_null()) {
|
||||||
|
return get_texture()->get_default_sampler();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return SamplerState::get_default();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
Loading…
x
Reference in New Issue
Block a user