mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 02:15:43 -04:00
Add ability to cache compiled GLSL shaders, remove unused ShaderUtilization
This commit is contained in:
parent
bc58335214
commit
6eb460c359
@ -1152,6 +1152,8 @@ extract_texture_data(Texture *tex, GraphicsStateGuardian *gsg) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void GraphicsEngine::
|
void GraphicsEngine::
|
||||||
dispatch_compute(const LVecBase3i &work_groups, const ShaderAttrib *sattr, GraphicsStateGuardian *gsg) {
|
dispatch_compute(const LVecBase3i &work_groups, const ShaderAttrib *sattr, GraphicsStateGuardian *gsg) {
|
||||||
|
nassertv(sattr->get_shader() != (Shader *)NULL);
|
||||||
|
|
||||||
ReMutexHolder holder(_lock);
|
ReMutexHolder holder(_lock);
|
||||||
|
|
||||||
CPT(RenderState) state = RenderState::make(sattr);
|
CPT(RenderState) state = RenderState::make(sattr);
|
||||||
@ -2334,50 +2336,6 @@ auto_adjust_capabilities(GraphicsStateGuardian *gsg) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shader_auto_utilization && (shader_utilization != SUT_none)) {
|
|
||||||
display_cat.error()
|
|
||||||
<< "Invalid panda config file: if you set the config-variable\n"
|
|
||||||
<< "shader_auto_utilization to true, you must set the config-variable"
|
|
||||||
<< "shader_utilization to 'none'.\n";
|
|
||||||
shader_utilization = SUT_none; // Not a fix. Just suppresses further error messages.
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shader_auto_utilization && !Shader::have_shader_utilization()) {
|
|
||||||
if (gsg->get_supports_basic_shaders()) {
|
|
||||||
Shader::set_shader_utilization(SUT_basic);
|
|
||||||
} else {
|
|
||||||
Shader::set_shader_utilization(SUT_none);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((Shader::get_shader_utilization() != SUT_none) &&
|
|
||||||
(!gsg->get_supports_basic_shaders())) {
|
|
||||||
|
|
||||||
// Overaggressive configuration detected
|
|
||||||
|
|
||||||
display_cat.error()
|
|
||||||
<< "The 'shader_utilization' config variable is set, meaning\n"
|
|
||||||
<< "that panda may try to generate shaders. However, the video \n"
|
|
||||||
<< "driver I'm trying to use does not support shaders.\n";
|
|
||||||
|
|
||||||
if (shader_utilization == SUT_none) {
|
|
||||||
display_cat.error()
|
|
||||||
<< "The 'shader_utilization' setting did not come from the config\n"
|
|
||||||
<< "file. In other words, it was altered procedurally.\n";
|
|
||||||
|
|
||||||
if (shader_auto_utilization) {
|
|
||||||
display_cat.error()
|
|
||||||
<< "It is possible that it was set by panda's automatic mechanisms,\n"
|
|
||||||
<< "which are currently enabled, because 'shader_auto_utilization' is\n"
|
|
||||||
<< "true. Panda's automatic mechanisms assume that if one\n"
|
|
||||||
<< "window supports shaders, then they all will.\n"
|
|
||||||
<< "This assumption works for most games, but not all.\n"
|
|
||||||
<< "In particular, it can fail if the game creates multiple windows\n"
|
|
||||||
<< "on multiple displays with different video cards.\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
@ -704,6 +704,12 @@ issue_parameters(int altered) {
|
|||||||
case Shader::SMP_cell15:
|
case Shader::SMP_cell15:
|
||||||
GLf(cgGLSetParameter1)(p, data[15]);
|
GLf(cgGLSetParameter1)(p, data[15]);
|
||||||
continue;
|
continue;
|
||||||
|
case Shader::SMP_cell14:
|
||||||
|
GLf(cgGLSetParameter1)(p, data[14]);
|
||||||
|
continue;
|
||||||
|
case Shader::SMP_cell13:
|
||||||
|
GLf(cgGLSetParameter1)(p, data[13]);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2492,11 +2492,15 @@ reset() {
|
|||||||
if (is_at_least_gl_version(4, 1) || has_extension("GL_ARB_get_program_binary")) {
|
if (is_at_least_gl_version(4, 1) || has_extension("GL_ARB_get_program_binary")) {
|
||||||
_glGetProgramBinary = (PFNGLGETPROGRAMBINARYPROC)
|
_glGetProgramBinary = (PFNGLGETPROGRAMBINARYPROC)
|
||||||
get_extension_func("glGetProgramBinary");
|
get_extension_func("glGetProgramBinary");
|
||||||
|
_glProgramBinary = (PFNGLPROGRAMBINARYPROC)
|
||||||
|
get_extension_func("glProgramBinary");
|
||||||
_glProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC)
|
_glProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC)
|
||||||
get_extension_func("glProgramParameteri");
|
get_extension_func("glProgramParameteri");
|
||||||
|
|
||||||
GLint num_binary_formats = 0;
|
GLint num_binary_formats = 0;
|
||||||
if (_glGetProgramBinary != NULL && _glProgramParameteri != NULL) {
|
if (_glGetProgramBinary != NULL &&
|
||||||
|
_glProgramBinary != NULL &&
|
||||||
|
_glProgramParameteri != NULL) {
|
||||||
glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &num_binary_formats);
|
glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &num_binary_formats);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -940,6 +940,7 @@ public:
|
|||||||
PFNGLDISPATCHCOMPUTEPROC _glDispatchCompute;
|
PFNGLDISPATCHCOMPUTEPROC _glDispatchCompute;
|
||||||
PFNGLMEMORYBARRIERPROC _glMemoryBarrier;
|
PFNGLMEMORYBARRIERPROC _glMemoryBarrier;
|
||||||
PFNGLGETPROGRAMBINARYPROC _glGetProgramBinary;
|
PFNGLGETPROGRAMBINARYPROC _glGetProgramBinary;
|
||||||
|
PFNGLPROGRAMBINARYPROC _glProgramBinary;
|
||||||
PFNGLGETINTERNALFORMATIVPROC _glGetInternalformativ;
|
PFNGLGETINTERNALFORMATIVPROC _glGetInternalformativ;
|
||||||
PFNGLVIEWPORTARRAYVPROC _glViewportArrayv;
|
PFNGLVIEWPORTARRAYVPROC _glViewportArrayv;
|
||||||
PFNGLSCISSORARRAYVPROC _glScissorArrayv;
|
PFNGLSCISSORARRAYVPROC _glScissorArrayv;
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
#include "fogAttrib.h"
|
#include "fogAttrib.h"
|
||||||
#include "lightAttrib.h"
|
#include "lightAttrib.h"
|
||||||
#include "clipPlaneAttrib.h"
|
#include "clipPlaneAttrib.h"
|
||||||
#include "ambientLight.h"
|
#include "bamCache.h"
|
||||||
|
|
||||||
TypeHandle CLP(ShaderContext)::_type_handle;
|
TypeHandle CLP(ShaderContext)::_type_handle;
|
||||||
|
|
||||||
@ -2872,6 +2872,32 @@ glsl_compile_and_link() {
|
|||||||
_glgsg->_glObjectLabel(GL_PROGRAM, _glsl_program, name.size(), name.data());
|
_glgsg->_glObjectLabel(GL_PROGRAM, _glsl_program, name.size(), name.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef OPENGLES
|
||||||
|
// Do we have a compiled program? Try to load that.
|
||||||
|
unsigned int format;
|
||||||
|
string binary;
|
||||||
|
if (_shader->get_compiled(format, binary)) {
|
||||||
|
_glgsg->_glProgramBinary(_glsl_program, format, binary.data(), binary.size());
|
||||||
|
|
||||||
|
GLint status;
|
||||||
|
_glgsg->_glGetProgramiv(_glsl_program, GL_LINK_STATUS, &status);
|
||||||
|
if (status == GL_TRUE) {
|
||||||
|
// Hooray, the precompiled shader worked.
|
||||||
|
if (GLCAT.is_debug()) {
|
||||||
|
GLCAT.debug() << "Loaded precompiled binary for GLSL shader "
|
||||||
|
<< _shader->get_filename() << "\n";
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bummer, it didn't work.. Oh well, just recompile the shader.
|
||||||
|
if (GLCAT.is_debug()) {
|
||||||
|
GLCAT.debug() << "Failure loading precompiled binary for GLSL shader "
|
||||||
|
<< _shader->get_filename() << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
bool valid = true;
|
bool valid = true;
|
||||||
|
|
||||||
if (!_shader->get_text(Shader::ST_vertex).empty()) {
|
if (!_shader->get_text(Shader::ST_vertex).empty()) {
|
||||||
@ -2936,8 +2962,17 @@ glsl_compile_and_link() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If we requested to retrieve the shader, we should indicate that before linking.
|
// If we requested to retrieve the shader, we should indicate that before linking.
|
||||||
#if !defined(NDEBUG) && !defined(OPENGLES)
|
#ifndef OPENGLES
|
||||||
if (gl_dump_compiled_shaders && _glgsg->_supports_get_program_binary) {
|
bool retrieve_binary = false;
|
||||||
|
if (_glgsg->_supports_get_program_binary) {
|
||||||
|
retrieve_binary = _shader->get_cache_compiled_shader();
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
if (gl_dump_compiled_shaders) {
|
||||||
|
retrieve_binary = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
_glgsg->_glProgramParameteri(_glsl_program, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE);
|
_glgsg->_glProgramParameteri(_glsl_program, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -2961,33 +2996,38 @@ glsl_compile_and_link() {
|
|||||||
// Report any warnings.
|
// Report any warnings.
|
||||||
glsl_report_program_errors(_glsl_program, false);
|
glsl_report_program_errors(_glsl_program, false);
|
||||||
|
|
||||||
// Dump the binary if requested.
|
#ifndef OPENGLES
|
||||||
#if !defined(NDEBUG) && !defined(OPENGLES)
|
if (retrieve_binary) {
|
||||||
if (gl_dump_compiled_shaders && _glgsg->_supports_get_program_binary) {
|
|
||||||
GLint length = 0;
|
GLint length = 0;
|
||||||
_glgsg->_glGetProgramiv(_glsl_program, GL_PROGRAM_BINARY_LENGTH, &length);
|
_glgsg->_glGetProgramiv(_glsl_program, GL_PROGRAM_BINARY_LENGTH, &length);
|
||||||
length += 2;
|
length += 2;
|
||||||
|
|
||||||
char filename[64];
|
char *binary = (char *)alloca(length);
|
||||||
static int gl_dump_count = 0;
|
|
||||||
sprintf(filename, "glsl_program%d.dump", gl_dump_count++);
|
|
||||||
|
|
||||||
char *binary = new char[length];
|
|
||||||
GLenum format;
|
GLenum format;
|
||||||
GLsizei num_bytes;
|
GLsizei num_bytes = 0;
|
||||||
_glgsg->_glGetProgramBinary(_glsl_program, length, &num_bytes, &format, (void*)binary);
|
_glgsg->_glGetProgramBinary(_glsl_program, length, &num_bytes, &format, (void*)binary);
|
||||||
|
|
||||||
pofstream s;
|
_shader->set_compiled(format, binary, num_bytes);
|
||||||
s.open(filename, ios::out | ios::binary | ios::trunc);
|
|
||||||
s.write(binary, num_bytes);
|
|
||||||
s.close();
|
|
||||||
|
|
||||||
GLCAT.info()
|
#ifndef NDEBUG
|
||||||
<< "Dumped " << num_bytes << " bytes of program binary with format 0x"
|
// Dump the binary if requested.
|
||||||
<< hex << format << dec << " to " << filename << "\n";
|
if (gl_dump_compiled_shaders) {
|
||||||
delete[] binary;
|
char filename[64];
|
||||||
}
|
static int gl_dump_count = 0;
|
||||||
|
sprintf(filename, "glsl_program%d.dump", gl_dump_count++);
|
||||||
|
|
||||||
|
pofstream s;
|
||||||
|
s.open(filename, ios::out | ios::binary | ios::trunc);
|
||||||
|
s.write(binary, num_bytes);
|
||||||
|
s.close();
|
||||||
|
|
||||||
|
GLCAT.info()
|
||||||
|
<< "Dumped " << num_bytes << " bytes of program binary with format 0x"
|
||||||
|
<< hex << format << dec << " to " << filename << "\n";
|
||||||
|
}
|
||||||
#endif // NDEBUG
|
#endif // NDEBUG
|
||||||
|
}
|
||||||
|
#endif // OPENGLES
|
||||||
|
|
||||||
_glgsg->report_my_gl_errors();
|
_glgsg->report_my_gl_errors();
|
||||||
return true;
|
return true;
|
||||||
|
@ -362,23 +362,6 @@ ConfigVariableDouble simple_image_threshold
|
|||||||
"simple images. Generally the value should be considerably "
|
"simple images. Generally the value should be considerably "
|
||||||
"less than 1."));
|
"less than 1."));
|
||||||
|
|
||||||
ConfigVariableEnum<ShaderUtilization> shader_utilization
|
|
||||||
("shader-utilization", SUT_none,
|
|
||||||
PRC_DESC("At times, panda may generate shaders. This variable controls what "
|
|
||||||
"kinds of shaders can be generated. If you set it to SUT_none, "
|
|
||||||
"shader generation will be be disabled. If you set it to SUT_basic, "
|
|
||||||
"then DX9 shaders may be generated, if you set it to SUT_advanced, "
|
|
||||||
"then DX10 shaders may be generated."));
|
|
||||||
|
|
||||||
ConfigVariableBool shader_auto_utilization
|
|
||||||
("shader-auto-utilization", false,
|
|
||||||
PRC_DESC("If this is true, then panda will wait until you open a window, "
|
|
||||||
"and then ask the window if it supports basic or advanced shaders. "
|
|
||||||
"If so, then the config variable shader-utilization will "
|
|
||||||
"automatically be adusted. The pitfall of doing this is that if "
|
|
||||||
"you then open a second window that doesn't support the same "
|
|
||||||
"capabilities, it will have no choice but to print an error message."));
|
|
||||||
|
|
||||||
ConfigVariableInt geom_cache_size
|
ConfigVariableInt geom_cache_size
|
||||||
("geom-cache-size", 5000,
|
("geom-cache-size", 5000,
|
||||||
PRC_DESC("Specifies the maximum number of entries in the cache "
|
PRC_DESC("Specifies the maximum number of entries in the cache "
|
||||||
@ -651,50 +634,3 @@ ConfigureFn(config_gobj) {
|
|||||||
UserVertexSlider::register_with_read_factory();
|
UserVertexSlider::register_with_read_factory();
|
||||||
UserVertexTransform::register_with_read_factory();
|
UserVertexTransform::register_with_read_factory();
|
||||||
}
|
}
|
||||||
|
|
||||||
ostream &
|
|
||||||
operator << (ostream &out, ShaderUtilization sgc) {
|
|
||||||
switch (sgc) {
|
|
||||||
case SUT_none:
|
|
||||||
return out << "none";
|
|
||||||
|
|
||||||
case SUT_basic:
|
|
||||||
return out << "basic";
|
|
||||||
|
|
||||||
case SUT_advanced:
|
|
||||||
return out << "advanced";
|
|
||||||
|
|
||||||
case SUT_unspecified:
|
|
||||||
return out << "unspecified";
|
|
||||||
}
|
|
||||||
|
|
||||||
return out << "**invalid ShaderUtilization (" << (int)sgc << ")**";
|
|
||||||
}
|
|
||||||
|
|
||||||
istream &
|
|
||||||
operator >> (istream &in, ShaderUtilization &sgc) {
|
|
||||||
string word;
|
|
||||||
in >> word;
|
|
||||||
|
|
||||||
if (cmp_nocase(word, "none") == 0 ||
|
|
||||||
cmp_nocase(word, "0") == 0 ||
|
|
||||||
cmp_nocase(word, "#f") == 0 ||
|
|
||||||
(!word.empty() && tolower(word[0]) == 'f')) {
|
|
||||||
sgc = SUT_none;
|
|
||||||
|
|
||||||
} else if (cmp_nocase(word, "basic") == 0 ||
|
|
||||||
cmp_nocase(word, "1") == 0 ||
|
|
||||||
cmp_nocase(word, "#t") == 0 ||
|
|
||||||
(!word.empty() && tolower(word[0]) == 't')) {
|
|
||||||
sgc = SUT_basic;
|
|
||||||
|
|
||||||
} else if (cmp_nocase(word, "advanced") == 0) {
|
|
||||||
sgc = SUT_advanced;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
gobj_cat->error() << "Invalid ShaderUtilization value: " << word << "\n";
|
|
||||||
sgc = SUT_none;
|
|
||||||
}
|
|
||||||
|
|
||||||
return in;
|
|
||||||
}
|
|
||||||
|
@ -29,18 +29,6 @@
|
|||||||
NotifyCategoryDecl(gobj, EXPCL_PANDA_GOBJ, EXPTP_PANDA_GOBJ);
|
NotifyCategoryDecl(gobj, EXPCL_PANDA_GOBJ, EXPTP_PANDA_GOBJ);
|
||||||
NotifyCategoryDecl(shader, EXPCL_PANDA_GOBJ, EXPTP_PANDA_GOBJ);
|
NotifyCategoryDecl(shader, EXPCL_PANDA_GOBJ, EXPTP_PANDA_GOBJ);
|
||||||
|
|
||||||
BEGIN_PUBLISH
|
|
||||||
enum ShaderUtilization {
|
|
||||||
SUT_none,
|
|
||||||
SUT_basic,
|
|
||||||
SUT_advanced,
|
|
||||||
SUT_unspecified,
|
|
||||||
};
|
|
||||||
END_PUBLISH
|
|
||||||
|
|
||||||
EXPCL_PANDA_GOBJ ostream &operator << (ostream &out, ShaderUtilization sut);
|
|
||||||
EXPCL_PANDA_GOBJ istream &operator >> (istream &in, ShaderUtilization &sut);
|
|
||||||
|
|
||||||
// Configure variables for gobj package.
|
// Configure variables for gobj package.
|
||||||
extern EXPCL_PANDA_GOBJ ConfigVariableInt max_texture_dimension;
|
extern EXPCL_PANDA_GOBJ ConfigVariableInt max_texture_dimension;
|
||||||
extern EXPCL_PANDA_GOBJ ConfigVariableDouble texture_scale;
|
extern EXPCL_PANDA_GOBJ ConfigVariableDouble texture_scale;
|
||||||
@ -77,9 +65,6 @@ extern EXPCL_PANDA_GOBJ ConfigVariableBool textures_header_only;
|
|||||||
extern EXPCL_PANDA_GOBJ ConfigVariableInt simple_image_size;
|
extern EXPCL_PANDA_GOBJ ConfigVariableInt simple_image_size;
|
||||||
extern EXPCL_PANDA_GOBJ ConfigVariableDouble simple_image_threshold;
|
extern EXPCL_PANDA_GOBJ ConfigVariableDouble simple_image_threshold;
|
||||||
|
|
||||||
extern EXPCL_PANDA_GOBJ ConfigVariableEnum<ShaderUtilization> shader_utilization;
|
|
||||||
extern EXPCL_PANDA_GOBJ ConfigVariableBool shader_auto_utilization;
|
|
||||||
|
|
||||||
extern EXPCL_PANDA_GOBJ ConfigVariableInt geom_cache_size;
|
extern EXPCL_PANDA_GOBJ ConfigVariableInt geom_cache_size;
|
||||||
extern EXPCL_PANDA_GOBJ ConfigVariableInt geom_cache_min_frames;
|
extern EXPCL_PANDA_GOBJ ConfigVariableInt geom_cache_min_frames;
|
||||||
extern EXPCL_PANDA_GOBJ ConfigVariableInt released_vbuffer_cache_size;
|
extern EXPCL_PANDA_GOBJ ConfigVariableInt released_vbuffer_cache_size;
|
||||||
|
@ -101,49 +101,6 @@ get_error_flag() const {
|
|||||||
return _error_flag;
|
return _error_flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: Shader::set_shader_utilization
|
|
||||||
// Access: Published, Static
|
|
||||||
// Description: Set this flag to SUT_none, SUT_basic, or
|
|
||||||
// SUT_advanced to limit panda's automatic shader
|
|
||||||
// generation facilities.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
INLINE void Shader::
|
|
||||||
set_shader_utilization(ShaderUtilization sut) {
|
|
||||||
_shader_utilization = sut;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: Shader::get_shader_utilization
|
|
||||||
// Access: Published, Static
|
|
||||||
// Description: This flag returns SUT_none, SUT_basic, or
|
|
||||||
// SUT_advanced and controls the automatic generation
|
|
||||||
// of shaders. It is initialized from the config
|
|
||||||
// variable of the same name, but it can be
|
|
||||||
// subsequently adjusted.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
INLINE ShaderUtilization Shader::
|
|
||||||
get_shader_utilization() {
|
|
||||||
if (_shader_utilization == SUT_unspecified) {
|
|
||||||
return shader_utilization;
|
|
||||||
} else {
|
|
||||||
return _shader_utilization;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: Shader::have_shader_utilization
|
|
||||||
// Access: Published, Static
|
|
||||||
// Description: If true, then get_shader_utilization has been
|
|
||||||
// set using set_shader_utilization.
|
|
||||||
// If false, then get_shader_utilization simply
|
|
||||||
// returns the config variable of the same name.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
INLINE bool Shader::
|
|
||||||
have_shader_utilization() {
|
|
||||||
return (_shader_utilization != SUT_unspecified);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: Shader::get_language
|
// Function: Shader::get_language
|
||||||
// Access: Published
|
// Access: Published
|
||||||
@ -155,6 +112,58 @@ get_language() const {
|
|||||||
return _language;
|
return _language;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Shader::has_fullpath
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns true if the fullpath has been set and
|
||||||
|
// is available. See set_fullpath().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool Shader::
|
||||||
|
has_fullpath() const {
|
||||||
|
return !_fullpath.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Shader::get_fullpath
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the fullpath that has been set. This is
|
||||||
|
// the full path to the file as it was found along the
|
||||||
|
// model-path.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE const Filename &Shader::
|
||||||
|
get_fullpath() const {
|
||||||
|
return _fullpath;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Shader::get_cache_compiled_shader
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns the setting of the cache_compiled_shader
|
||||||
|
// flag. See set_cache_compiled_shader().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool Shader::
|
||||||
|
get_cache_compiled_shader() const {
|
||||||
|
return _cache_compiled_shader;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Shader::set_cache_compiled_shader
|
||||||
|
// Access: Public
|
||||||
|
// Description: Sets the cache_compiled_shader flag. When this is
|
||||||
|
// set, the next time the Shader is loaded on a GSG, it
|
||||||
|
// will automatically extract the compiled shader from
|
||||||
|
// the GSG and save it to the global BamCache.
|
||||||
|
//
|
||||||
|
// This is used to store compiled shaders in the
|
||||||
|
// BamCache. This flag should not be set explicitly; it
|
||||||
|
// is set automatically by the ShaderPool when
|
||||||
|
// model-cache-compiled-shaders is set true.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void Shader::
|
||||||
|
set_cache_compiled_shader(bool flag) {
|
||||||
|
_cache_compiled_shader = flag;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: Shader::ShaderCapabilities Constructor
|
// Function: Shader::ShaderCapabilities Constructor
|
||||||
// Access: Public
|
// Access: Public
|
||||||
@ -802,6 +811,7 @@ INLINE void Shader::ShaderFile::
|
|||||||
read_datagram(DatagramIterator &scan) {
|
read_datagram(DatagramIterator &scan) {
|
||||||
short count = scan.get_uint8();
|
short count = scan.get_uint8();
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
|
_separate = true;
|
||||||
if (count-- > 0) _vertex = scan.get_string();
|
if (count-- > 0) _vertex = scan.get_string();
|
||||||
if (count-- > 0) _fragment = scan.get_string();
|
if (count-- > 0) _fragment = scan.get_string();
|
||||||
if (count-- > 0) _geometry = scan.get_string();
|
if (count-- > 0) _geometry = scan.get_string();
|
||||||
@ -812,6 +822,7 @@ read_datagram(DatagramIterator &scan) {
|
|||||||
scan.get_string();
|
scan.get_string();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
_separate = false;
|
||||||
_shared = scan.get_string();
|
_shared = scan.get_string();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "preparedGraphicsObjects.h"
|
#include "preparedGraphicsObjects.h"
|
||||||
#include "virtualFileSystem.h"
|
#include "virtualFileSystem.h"
|
||||||
#include "config_util.h"
|
#include "config_util.h"
|
||||||
|
#include "bamCache.h"
|
||||||
|
|
||||||
#ifdef HAVE_CG
|
#ifdef HAVE_CG
|
||||||
#include <Cg/cg.h>
|
#include <Cg/cg.h>
|
||||||
@ -28,7 +29,6 @@ Shader::ShaderTable Shader::_load_table;
|
|||||||
Shader::ShaderTable Shader::_make_table;
|
Shader::ShaderTable Shader::_make_table;
|
||||||
Shader::ShaderCaps Shader::_default_caps;
|
Shader::ShaderCaps Shader::_default_caps;
|
||||||
int Shader::_shaders_generated;
|
int Shader::_shaders_generated;
|
||||||
ShaderUtilization Shader::_shader_utilization = SUT_unspecified;
|
|
||||||
|
|
||||||
#ifdef HAVE_CG
|
#ifdef HAVE_CG
|
||||||
CGcontext Shader::_cg_context = 0;
|
CGcontext Shader::_cg_context = 0;
|
||||||
@ -1460,7 +1460,6 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: Shader::clear_parameters
|
// Function: Shader::clear_parameters
|
||||||
// Access: Private
|
// Access: Private
|
||||||
@ -1473,6 +1472,38 @@ clear_parameters() {
|
|||||||
_tex_spec.clear();
|
_tex_spec.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Shader::set_compiled
|
||||||
|
// Access: Private
|
||||||
|
// Description: Called by the back-end when the shader has compiled
|
||||||
|
// data available.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void Shader::
|
||||||
|
set_compiled(unsigned int format, const char *data, size_t length) {
|
||||||
|
_compiled_format = format;
|
||||||
|
_compiled_binary.assign(data, length);
|
||||||
|
|
||||||
|
// Store the compiled shader in the cache.
|
||||||
|
if (_cache_compiled_shader && !_record.is_null()) {
|
||||||
|
_record->set_data(this);
|
||||||
|
|
||||||
|
BamCache *cache = BamCache::get_global_ptr();
|
||||||
|
cache->store(_record);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Shader::get_compiled
|
||||||
|
// Access: Private
|
||||||
|
// Description: Called by the back-end to retrieve compiled data.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool Shader::
|
||||||
|
get_compiled(unsigned int &format, string &binary) const {
|
||||||
|
format = _compiled_format;
|
||||||
|
binary = _compiled_binary;
|
||||||
|
return !binary.empty();
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef HAVE_CG
|
#ifdef HAVE_CG
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: Shader::cg_parameter_type
|
// Function: Shader::cg_parameter_type
|
||||||
@ -2204,7 +2235,8 @@ Shader(ShaderLanguage lang) :
|
|||||||
_loaded(false),
|
_loaded(false),
|
||||||
_language(lang),
|
_language(lang),
|
||||||
_last_modified(0),
|
_last_modified(0),
|
||||||
_mat_deps(0)
|
_mat_deps(0),
|
||||||
|
_cache_compiled_shader(false)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_CG
|
#ifdef HAVE_CG
|
||||||
_cg_vprogram = 0;
|
_cg_vprogram = 0;
|
||||||
@ -2234,7 +2266,7 @@ Shader(ShaderLanguage lang) :
|
|||||||
// Returns a boolean indicating success or failure.
|
// Returns a boolean indicating success or failure.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool Shader::
|
bool Shader::
|
||||||
read(const ShaderFile &sfile) {
|
read(const ShaderFile &sfile, BamCacheRecord *record) {
|
||||||
_text._separate = sfile._separate;
|
_text._separate = sfile._separate;
|
||||||
|
|
||||||
if (sfile._separate) {
|
if (sfile._separate) {
|
||||||
@ -2244,30 +2276,37 @@ read(const ShaderFile &sfile) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sfile._vertex.empty() && !do_read_source(_text._vertex, sfile._vertex)) {
|
if (!sfile._vertex.empty() &&
|
||||||
|
!do_read_source(_text._vertex, sfile._vertex, record)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!sfile._fragment.empty() && !do_read_source(_text._fragment, sfile._fragment)) {
|
if (!sfile._fragment.empty() &&
|
||||||
|
!do_read_source(_text._fragment, sfile._fragment, record)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!sfile._geometry.empty() && !do_read_source(_text._geometry, sfile._geometry)) {
|
if (!sfile._geometry.empty() &&
|
||||||
|
!do_read_source(_text._geometry, sfile._geometry, record)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!sfile._tess_control.empty() && !do_read_source(_text._tess_control, sfile._tess_control)) {
|
if (!sfile._tess_control.empty() &&
|
||||||
|
!do_read_source(_text._tess_control, sfile._tess_control, record)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!sfile._tess_evaluation.empty() && !do_read_source(_text._tess_evaluation, sfile._tess_evaluation)) {
|
if (!sfile._tess_evaluation.empty() &&
|
||||||
|
!do_read_source(_text._tess_evaluation, sfile._tess_evaluation, record)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!sfile._compute.empty() && !do_read_source(_text._compute, sfile._compute)) {
|
if (!sfile._compute.empty() &&
|
||||||
|
!do_read_source(_text._compute, sfile._compute, record)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
_filename = sfile;
|
_filename = sfile;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (!do_read_source(_text._shared, sfile._shared)) {
|
if (!do_read_source(_text._shared, sfile._shared, record)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
_fullpath = _source_files[0];
|
||||||
_filename = sfile;
|
_filename = sfile;
|
||||||
|
|
||||||
// Determine which language the shader is written in.
|
// Determine which language the shader is written in.
|
||||||
@ -2323,12 +2362,12 @@ read(const ShaderFile &sfile) {
|
|||||||
// bad enough to consider it 'invalid'.
|
// bad enough to consider it 'invalid'.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool Shader::
|
bool Shader::
|
||||||
do_read_source(string &into, const Filename &fn) {
|
do_read_source(string &into, const Filename &fn, BamCacheRecord *record) {
|
||||||
if (_language == SL_GLSL && glsl_preprocess) {
|
if (_language == SL_GLSL && glsl_preprocess) {
|
||||||
// Preprocess the GLSL file as we read it.
|
// Preprocess the GLSL file as we read it.
|
||||||
set<Filename> open_files;
|
set<Filename> open_files;
|
||||||
ostringstream sstr;
|
ostringstream sstr;
|
||||||
if (!r_preprocess_source(sstr, fn, Filename(), open_files)) {
|
if (!r_preprocess_source(sstr, fn, Filename(), open_files, record)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
into = sstr.str();
|
into = sstr.str();
|
||||||
@ -2350,6 +2389,9 @@ do_read_source(string &into, const Filename &fn) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (record != (BamCacheRecord *)NULL) {
|
||||||
|
record->add_dependent_file(vf);
|
||||||
|
}
|
||||||
_last_modified = max(_last_modified, vf->get_timestamp());
|
_last_modified = max(_last_modified, vf->get_timestamp());
|
||||||
_source_files.push_back(vf->get_filename());
|
_source_files.push_back(vf->get_filename());
|
||||||
}
|
}
|
||||||
@ -2368,7 +2410,8 @@ do_read_source(string &into, const Filename &fn) {
|
|||||||
bool Shader::
|
bool Shader::
|
||||||
r_preprocess_source(ostream &out, const Filename &fn,
|
r_preprocess_source(ostream &out, const Filename &fn,
|
||||||
const Filename &source_dir,
|
const Filename &source_dir,
|
||||||
set<Filename> &once_files, int depth) {
|
set<Filename> &once_files,
|
||||||
|
BamCacheRecord *record, int depth) {
|
||||||
|
|
||||||
if (depth > glsl_include_recursion_limit) {
|
if (depth > glsl_include_recursion_limit) {
|
||||||
shader_cat.error()
|
shader_cat.error()
|
||||||
@ -2402,6 +2445,9 @@ r_preprocess_source(ostream &out, const Filename &fn,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (record != (BamCacheRecord *)NULL) {
|
||||||
|
record->add_dependent_file(vf);
|
||||||
|
}
|
||||||
_last_modified = max(_last_modified, vf->get_timestamp());
|
_last_modified = max(_last_modified, vf->get_timestamp());
|
||||||
_source_files.push_back(full_fn);
|
_source_files.push_back(full_fn);
|
||||||
|
|
||||||
@ -2483,7 +2529,7 @@ r_preprocess_source(ostream &out, const Filename &fn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// OK, great. Process the include.
|
// OK, great. Process the include.
|
||||||
if (!r_preprocess_source(out, incfn, source_dir, once_files, depth + 1)) {
|
if (!r_preprocess_source(out, incfn, source_dir, once_files, record, depth + 1)) {
|
||||||
// An error occurred. Pass on the failure.
|
// An error occurred. Pass on the failure.
|
||||||
shader_cat.error(false) << "included at line "
|
shader_cat.error(false) << "included at line "
|
||||||
<< lineno << " of file " << fn << ":\n " << line << "\n";
|
<< lineno << " of file " << fn << ":\n " << line << "\n";
|
||||||
@ -2768,6 +2814,14 @@ load_compute(ShaderLanguage lang, const Filename &fn) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Filename fullpath(fn);
|
||||||
|
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
|
||||||
|
if (!vfs->resolve_filename(fullpath, get_model_path())) {
|
||||||
|
shader_cat.error()
|
||||||
|
<< "Could not find compute shader file: " << fn << "\n";
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
ShaderFile sfile;
|
ShaderFile sfile;
|
||||||
sfile._separate = true;
|
sfile._separate = true;
|
||||||
sfile._compute = fn;
|
sfile._compute = fn;
|
||||||
@ -2785,11 +2839,29 @@ load_compute(ShaderLanguage lang, const Filename &fn) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BamCache *cache = BamCache::get_global_ptr();
|
||||||
|
PT(BamCacheRecord) record = cache->lookup(fullpath, "sho");
|
||||||
|
if (record != (BamCacheRecord *)NULL) {
|
||||||
|
if (record->has_data()) {
|
||||||
|
shader_cat.info()
|
||||||
|
<< "Compute shader " << fn << " was found in disk cache.\n";
|
||||||
|
|
||||||
|
return DCAST(Shader, record->get_data());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PT(Shader) shader = new Shader(lang);
|
PT(Shader) shader = new Shader(lang);
|
||||||
if (!shader->read(sfile)) {
|
|
||||||
|
if (!shader->read(sfile, record)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// It makes little sense to cache the shader before compilation, so
|
||||||
|
// we keep the record for when we have the compiled the shader.
|
||||||
|
swap(shader->_record, record);
|
||||||
|
shader->_cache_compiled_shader = BamCache::get_global_ptr()->get_cache_compiled_shaders();
|
||||||
|
shader->_fullpath = shader->_source_files[0];
|
||||||
|
|
||||||
_load_table[sfile] = shader;
|
_load_table[sfile] = shader;
|
||||||
return shader;
|
return shader;
|
||||||
}
|
}
|
||||||
@ -3195,11 +3267,9 @@ clear() {
|
|||||||
_active_vprofile = CG_PROFILE_UNKNOWN;
|
_active_vprofile = CG_PROFILE_UNKNOWN;
|
||||||
_active_fprofile = CG_PROFILE_UNKNOWN;
|
_active_fprofile = CG_PROFILE_UNKNOWN;
|
||||||
_active_gprofile = CG_PROFILE_UNKNOWN;
|
_active_gprofile = CG_PROFILE_UNKNOWN;
|
||||||
_active_fprofile = CG_PROFILE_UNKNOWN;
|
|
||||||
_ultimate_vprofile = CG_PROFILE_UNKNOWN;
|
_ultimate_vprofile = CG_PROFILE_UNKNOWN;
|
||||||
_ultimate_fprofile = CG_PROFILE_UNKNOWN;
|
_ultimate_fprofile = CG_PROFILE_UNKNOWN;
|
||||||
_ultimate_gprofile = CG_PROFILE_UNKNOWN;
|
_ultimate_gprofile = CG_PROFILE_UNKNOWN;
|
||||||
_ultimate_fprofile = CG_PROFILE_UNKNOWN;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3211,7 +3281,7 @@ clear() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void Shader::
|
void Shader::
|
||||||
register_with_read_factory() {
|
register_with_read_factory() {
|
||||||
//BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
|
BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -3226,6 +3296,9 @@ write_datagram(BamWriter *manager, Datagram &dg) {
|
|||||||
dg.add_bool(_loaded);
|
dg.add_bool(_loaded);
|
||||||
_filename.write_datagram(dg);
|
_filename.write_datagram(dg);
|
||||||
_text.write_datagram(dg);
|
_text.write_datagram(dg);
|
||||||
|
|
||||||
|
dg.add_uint32(_compiled_format);
|
||||||
|
dg.add_string(_compiled_binary);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -3260,4 +3333,7 @@ fillin(DatagramIterator &scan, BamReader *manager) {
|
|||||||
_loaded = scan.get_bool();
|
_loaded = scan.get_bool();
|
||||||
_filename.read_datagram(scan);
|
_filename.read_datagram(scan);
|
||||||
_text.read_datagram(scan);
|
_text.read_datagram(scan);
|
||||||
|
|
||||||
|
_compiled_format = scan.get_uint32();
|
||||||
|
_compiled_binary = scan.get_string();
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,8 @@ typedef struct _CGprogram *CGprogram;
|
|||||||
typedef struct _CGparameter *CGparameter;
|
typedef struct _CGparameter *CGparameter;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
class BamCacheRecord;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Class : Shader
|
// Class : Shader
|
||||||
// Summary: The Shader class is meant to select the Shader Language,
|
// Summary: The Shader class is meant to select the Shader Language,
|
||||||
@ -103,9 +105,11 @@ PUBLISHED:
|
|||||||
INLINE bool get_error_flag() const;
|
INLINE bool get_error_flag() const;
|
||||||
INLINE ShaderLanguage get_language() const;
|
INLINE ShaderLanguage get_language() const;
|
||||||
|
|
||||||
INLINE static ShaderUtilization get_shader_utilization();
|
INLINE bool has_fullpath() const;
|
||||||
INLINE static void set_shader_utilization(ShaderUtilization utl);
|
INLINE const Filename &get_fullpath() const;
|
||||||
INLINE static bool have_shader_utilization();
|
|
||||||
|
INLINE bool get_cache_compiled_shader() const;
|
||||||
|
INLINE void set_cache_compiled_shader(bool flag);
|
||||||
|
|
||||||
void prepare(PreparedGraphicsObjects *prepared_objects);
|
void prepare(PreparedGraphicsObjects *prepared_objects);
|
||||||
bool is_prepared(PreparedGraphicsObjects *prepared_objects) const;
|
bool is_prepared(PreparedGraphicsObjects *prepared_objects) const;
|
||||||
@ -507,6 +511,9 @@ public:
|
|||||||
|
|
||||||
void clear_parameters();
|
void clear_parameters();
|
||||||
|
|
||||||
|
void set_compiled(unsigned int format, const char *data, size_t length);
|
||||||
|
bool get_compiled(unsigned int &format, string &binary) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#ifdef HAVE_CG
|
#ifdef HAVE_CG
|
||||||
ShaderArgClass cg_parameter_class(CGparameter p);
|
ShaderArgClass cg_parameter_class(CGparameter p);
|
||||||
@ -557,18 +564,25 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
ShaderFile _filename;
|
ShaderFile _filename;
|
||||||
|
Filename _fullpath;
|
||||||
int _parse;
|
int _parse;
|
||||||
bool _loaded;
|
bool _loaded;
|
||||||
ShaderLanguage _language;
|
ShaderLanguage _language;
|
||||||
pvector<Filename> _included_files;
|
|
||||||
|
typedef pvector<Filename> Filenames;
|
||||||
|
Filenames _included_files;
|
||||||
|
|
||||||
// Stores full paths, and includes the fullpaths of the shaders
|
// Stores full paths, and includes the fullpaths of the shaders
|
||||||
// themselves as well as the includes.
|
// themselves as well as the includes.
|
||||||
pvector<Filename> _source_files;
|
Filenames _source_files;
|
||||||
time_t _last_modified;
|
time_t _last_modified;
|
||||||
|
|
||||||
|
PT(BamCacheRecord) _record;
|
||||||
|
bool _cache_compiled_shader;
|
||||||
|
unsigned int _compiled_format;
|
||||||
|
string _compiled_binary;
|
||||||
|
|
||||||
static ShaderCaps _default_caps;
|
static ShaderCaps _default_caps;
|
||||||
static ShaderUtilization _shader_utilization;
|
|
||||||
static int _shaders_generated;
|
static int _shaders_generated;
|
||||||
|
|
||||||
typedef pmap<ShaderFile, PT(Shader)> ShaderTable;
|
typedef pmap<ShaderFile, PT(Shader)> ShaderTable;
|
||||||
@ -587,11 +601,12 @@ private:
|
|||||||
|
|
||||||
Shader(ShaderLanguage lang);
|
Shader(ShaderLanguage lang);
|
||||||
|
|
||||||
bool read(const ShaderFile &sfile);
|
bool read(const ShaderFile &sfile, BamCacheRecord *record = NULL);
|
||||||
bool do_read_source(string &into, const Filename &fn);
|
bool do_read_source(string &into, const Filename &fn, BamCacheRecord *record);
|
||||||
bool r_preprocess_source(ostream &out, const Filename &fn,
|
bool r_preprocess_source(ostream &out, const Filename &fn,
|
||||||
const Filename &source_dir,
|
const Filename &source_dir,
|
||||||
set<Filename> &open_files, int depth = 0);
|
set<Filename> &open_files,
|
||||||
|
BamCacheRecord *record, int depth = 0);
|
||||||
|
|
||||||
bool check_modified() const;
|
bool check_modified() const;
|
||||||
|
|
||||||
|
@ -504,7 +504,6 @@ init_libpgraph() {
|
|||||||
ShadeModelAttrib::register_with_read_factory();
|
ShadeModelAttrib::register_with_read_factory();
|
||||||
ShaderInput::register_with_read_factory();
|
ShaderInput::register_with_read_factory();
|
||||||
ShaderAttrib::register_with_read_factory();
|
ShaderAttrib::register_with_read_factory();
|
||||||
Shader::register_with_read_factory();
|
|
||||||
ShowBoundsEffect::register_with_read_factory();
|
ShowBoundsEffect::register_with_read_factory();
|
||||||
TexMatrixAttrib::register_with_read_factory();
|
TexMatrixAttrib::register_with_read_factory();
|
||||||
TexProjectorEffect::register_with_read_factory();
|
TexProjectorEffect::register_with_read_factory();
|
||||||
|
@ -142,6 +142,35 @@ get_cache_compressed_textures() const {
|
|||||||
return _cache_compressed_textures && _active;
|
return _cache_compressed_textures && _active;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: BamCache::set_cache_compiled_shaders
|
||||||
|
// Access: Published
|
||||||
|
// Description: Indicates whether compiled shader programs will be
|
||||||
|
// stored in the cache, as binary .sho files. This
|
||||||
|
// may not be supported by all shader languages or
|
||||||
|
// graphics renderers.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void BamCache::
|
||||||
|
set_cache_compiled_shaders(bool flag) {
|
||||||
|
ReMutexHolder holder(_lock);
|
||||||
|
_cache_compiled_shaders = flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: BamCache::get_cache_compiled_shaders
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns whether compiled shader programs will be
|
||||||
|
// stored in the cache, as binary .txo files. See
|
||||||
|
// set_cache_compiled_shaders().
|
||||||
|
//
|
||||||
|
// This also returns false if get_active() is false.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool BamCache::
|
||||||
|
get_cache_compiled_shaders() const {
|
||||||
|
ReMutexHolder holder(_lock);
|
||||||
|
return _cache_compiled_shaders && _active;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: BamCache::get_root
|
// Function: BamCache::get_root
|
||||||
// Access: Published
|
// Access: Published
|
||||||
|
@ -74,6 +74,12 @@ BamCache() :
|
|||||||
"by the GSG. This may be set in conjunction with "
|
"by the GSG. This may be set in conjunction with "
|
||||||
"model-cache-textures, or it may be independent."));
|
"model-cache-textures, or it may be independent."));
|
||||||
|
|
||||||
|
ConfigVariableBool model_cache_compiled_shaders
|
||||||
|
("model-cache-compiled-shaders", false,
|
||||||
|
PRC_DESC("If this is set to true, compiled shaders will be cached "
|
||||||
|
"in the model cache, in their binary form as downloaded "
|
||||||
|
"by the GSG."));
|
||||||
|
|
||||||
ConfigVariableInt model_cache_max_kbytes
|
ConfigVariableInt model_cache_max_kbytes
|
||||||
("model-cache-max-kbytes", 10485760,
|
("model-cache-max-kbytes", 10485760,
|
||||||
PRC_DESC("This is the maximum size of the model cache, in kilobytes."));
|
PRC_DESC("This is the maximum size of the model cache, in kilobytes."));
|
||||||
@ -81,6 +87,7 @@ BamCache() :
|
|||||||
_cache_models = model_cache_models;
|
_cache_models = model_cache_models;
|
||||||
_cache_textures = model_cache_textures;
|
_cache_textures = model_cache_textures;
|
||||||
_cache_compressed_textures = model_cache_compressed_textures;
|
_cache_compressed_textures = model_cache_compressed_textures;
|
||||||
|
_cache_compiled_shaders = model_cache_compiled_shaders;
|
||||||
|
|
||||||
_flush_time = model_cache_flush;
|
_flush_time = model_cache_flush;
|
||||||
_max_kbytes = model_cache_max_kbytes;
|
_max_kbytes = model_cache_max_kbytes;
|
||||||
|
@ -61,6 +61,9 @@ PUBLISHED:
|
|||||||
INLINE void set_cache_compressed_textures(bool flag);
|
INLINE void set_cache_compressed_textures(bool flag);
|
||||||
INLINE bool get_cache_compressed_textures() const;
|
INLINE bool get_cache_compressed_textures() const;
|
||||||
|
|
||||||
|
INLINE void set_cache_compiled_shaders(bool flag);
|
||||||
|
INLINE bool get_cache_compiled_shaders() const;
|
||||||
|
|
||||||
void set_root(const Filename &root);
|
void set_root(const Filename &root);
|
||||||
INLINE Filename get_root() const;
|
INLINE Filename get_root() const;
|
||||||
|
|
||||||
@ -92,6 +95,8 @@ PUBLISHED:
|
|||||||
MAKE_PROPERTY(cache_textures, get_cache_textures, set_cache_textures);
|
MAKE_PROPERTY(cache_textures, get_cache_textures, set_cache_textures);
|
||||||
MAKE_PROPERTY(cache_compressed_textures, get_cache_compressed_textures,
|
MAKE_PROPERTY(cache_compressed_textures, get_cache_compressed_textures,
|
||||||
set_cache_compressed_textures);
|
set_cache_compressed_textures);
|
||||||
|
MAKE_PROPERTY(cache_compiled_shaders, get_cache_compiled_shaders,
|
||||||
|
set_cache_compiled_shaders);
|
||||||
MAKE_PROPERTY(root, get_root, set_root);
|
MAKE_PROPERTY(root, get_root, set_root);
|
||||||
MAKE_PROPERTY(flush_time, get_flush_time, set_flush_time);
|
MAKE_PROPERTY(flush_time, get_flush_time, set_flush_time);
|
||||||
MAKE_PROPERTY(cache_max_kbytes, get_cache_max_kbytes, set_cache_max_kbytes);
|
MAKE_PROPERTY(cache_max_kbytes, get_cache_max_kbytes, set_cache_max_kbytes);
|
||||||
@ -130,6 +135,7 @@ private:
|
|||||||
bool _cache_models;
|
bool _cache_models;
|
||||||
bool _cache_textures;
|
bool _cache_textures;
|
||||||
bool _cache_compressed_textures;
|
bool _cache_compressed_textures;
|
||||||
|
bool _cache_compiled_shaders;
|
||||||
bool _read_only;
|
bool _read_only;
|
||||||
Filename _root;
|
Filename _root;
|
||||||
int _flush_time;
|
int _flush_time;
|
||||||
|
@ -188,6 +188,27 @@ add_dependent_file(const Filename &pathname) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: BamCacheRecord::add_dependent_file
|
||||||
|
// Access: Published
|
||||||
|
// Description: Variant of add_dependent_file that takes an already
|
||||||
|
// opened VirtualFile.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void BamCacheRecord::
|
||||||
|
add_dependent_file(const VirtualFile *file) {
|
||||||
|
_files.push_back(DependentFile());
|
||||||
|
DependentFile &dfile = _files.back();
|
||||||
|
dfile._pathname = file->get_filename();
|
||||||
|
dfile._pathname.make_absolute();
|
||||||
|
|
||||||
|
dfile._timestamp = file->get_timestamp();
|
||||||
|
dfile._size = file->get_file_size();
|
||||||
|
|
||||||
|
if (dfile._pathname == _source_pathname) {
|
||||||
|
_source_timestamp = dfile._timestamp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: BamCacheRecord::output
|
// Function: BamCacheRecord::output
|
||||||
// Access: Published
|
// Access: Published
|
||||||
|
@ -26,6 +26,7 @@ class Datagram;
|
|||||||
class DatagramIterator;
|
class DatagramIterator;
|
||||||
class FactoryParams;
|
class FactoryParams;
|
||||||
class BamCacheRecord;
|
class BamCacheRecord;
|
||||||
|
class VirtualFile;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Class : BamCacheRecord
|
// Class : BamCacheRecord
|
||||||
@ -66,6 +67,7 @@ PUBLISHED:
|
|||||||
bool dependents_unchanged() const;
|
bool dependents_unchanged() const;
|
||||||
void clear_dependent_files();
|
void clear_dependent_files();
|
||||||
void add_dependent_file(const Filename &pathname);
|
void add_dependent_file(const Filename &pathname);
|
||||||
|
void add_dependent_file(const VirtualFile *file);
|
||||||
|
|
||||||
INLINE bool has_data() const;
|
INLINE bool has_data() const;
|
||||||
INLINE void clear_data();
|
INLINE void clear_data();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user