Cg fixes for DX9

This commit is contained in:
rdb 2016-07-10 14:06:01 +02:00
parent fa7730819f
commit c34758ea5c
4 changed files with 92 additions and 51 deletions

View File

@ -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 ------------------------

View File

@ -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;
} }

View File

@ -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);
} }
} }

View File

@ -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();
}
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////