Bläddra i källkod

Cg fixes for DX9

rdb 9 år sedan
förälder
incheckning
c34758ea5c

+ 1 - 0
doc/ReleaseNotes

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

+ 27 - 2
panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx

@@ -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);
-  return result;
+    if (_supports_basic_shaders) {
+      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;
 }
 }
 
 

+ 55 - 46
panda/src/dxgsg9/dxShaderContext9.cxx

@@ -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
-    for (int i=0; i<(int)_shader->_ptr_spec.size(); i++) {
-      if(altered & (_shader->_ptr_spec[i]._dep[0] | _shader->_ptr_spec[i]._dep[1])){
-#ifdef HAVE_CG
-        const Shader::ShaderPtrSpec& _ptr = _shader->_ptr_spec[i];
-        Shader::ShaderPtrData* _ptr_data =
-          const_cast< Shader::ShaderPtrData*>(gsg->fetch_ptr_parameter(_ptr));
+    // Iterate through _ptr parameters
+    for (size_t i = 0; i < _shader->_ptr_spec.size(); ++i) {
+      const Shader::ShaderPtrSpec &spec = _shader->_ptr_spec[i];
+
+      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
+        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++) {
-      if (altered & (_shader->_mat_spec[i]._dep[0] | _shader->_mat_spec[i]._dep[1])) {
-        CGparameter p = _cg_parameter_map[_shader->_mat_spec[i]._id._seqno];
+    for (size_t i = 0; i < _shader->_mat_spec.size(); ++i) {
+      Shader::ShaderMatSpec &spec = _shader->_mat_spec[i];
+
+      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]) {
-              name = _shader->_mat_spec[i]._arg [0] -> get_basename ( );
+            if (spec._arg[0]) {
+              name = spec._arg[0]->get_basename();
             }
             }
 
 
             dxgsg9_cat.error()
             dxgsg9_cat.error()
-              << "NAME  " << name << "\n"
-              << "MAT TYPE  "
-              << _shader->_mat_spec[i]._piece
-              << " cgD3D9SetUniform failed "
-              << D3DERRORSTRING(hr);
+              << "NAME  " << name << "\n" << "MAT TYPE  " << spec._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)
-{
-  if (prev) prev->disable_shader_texture_bindings(gsg);
+update_shader_texture_bindings(CLP(ShaderContext) *prev, GSG *gsg) {
+  if (prev) {
+    prev->disable_shader_texture_bindings(gsg);
+  }
 
 
 #ifdef HAVE_CG
 #ifdef HAVE_CG
   if (_cg_program) {
   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];
+    for (size_t i = 0; i < _shader->_tex_spec.size(); ++i) {
+      const Shader::ShaderTexSpec &spec = _shader->_tex_spec[i];
+      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) {
-        const ShaderInput *input = gsg->_target_shader->get_shader_input(id);
+      if (spec._name != NULL) {
+        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);
     }
     }
   }
   }

+ 9 - 3
panda/src/pgraph/shaderInput.I

@@ -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)
-    ? get_texture()->get_default_sampler()
-    : _sampler;
+  if (_type != M_texture) {
+    return _sampler;
+
+  } else if (!_value.is_null()) {
+    return get_texture()->get_default_sampler();
+
+  } else {
+    return SamplerState::get_default();
+  }
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////