mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 01:07:51 -04:00
glsl: make ParamVecBase4 and ParamVecBase4i work with ptr inputs
This commit is contained in:
parent
66ea0471a0
commit
6df700939a
@ -1901,6 +1901,14 @@ fetch_ptr_parameter(const Shader::ShaderPtrSpec& spec) {
|
|||||||
return (_target_shader->get_shader_input_ptr(spec._arg));
|
return (_target_shader->get_shader_input_ptr(spec._arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
bool GraphicsStateGuardian::
|
||||||
|
fetch_ptr_parameter(const Shader::ShaderPtrSpec& spec, Shader::ShaderPtrData &data) {
|
||||||
|
return _target_shader->get_shader_input_ptr(spec._arg, data);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes the specified DisplayRegion current. All future drawing and clear
|
* Makes the specified DisplayRegion current. All future drawing and clear
|
||||||
* operations will be constrained within the given DisplayRegion.
|
* operations will be constrained within the given DisplayRegion.
|
||||||
|
@ -339,6 +339,7 @@ public:
|
|||||||
PT(Texture) fetch_specified_texture(Shader::ShaderTexSpec &spec,
|
PT(Texture) fetch_specified_texture(Shader::ShaderTexSpec &spec,
|
||||||
SamplerState &sampler, int &view);
|
SamplerState &sampler, int &view);
|
||||||
const Shader::ShaderPtrData *fetch_ptr_parameter(const Shader::ShaderPtrSpec& spec);
|
const Shader::ShaderPtrData *fetch_ptr_parameter(const Shader::ShaderPtrSpec& spec);
|
||||||
|
bool fetch_ptr_parameter(const Shader::ShaderPtrSpec &spec, Shader::ShaderPtrData &data);
|
||||||
|
|
||||||
virtual void prepare_display_region(DisplayRegionPipelineReader *dr);
|
virtual void prepare_display_region(DisplayRegionPipelineReader *dr);
|
||||||
virtual void clear_before_callback();
|
virtual void clear_before_callback();
|
||||||
|
@ -2110,8 +2110,8 @@ issue_parameters(int altered) {
|
|||||||
for (int i = 0; i < (int)_shader->_ptr_spec.size(); ++i) {
|
for (int i = 0; i < (int)_shader->_ptr_spec.size(); ++i) {
|
||||||
Shader::ShaderPtrSpec &spec = _shader->_ptr_spec[i];
|
Shader::ShaderPtrSpec &spec = _shader->_ptr_spec[i];
|
||||||
|
|
||||||
const Shader::ShaderPtrData* ptr_data = _glgsg->fetch_ptr_parameter(spec);
|
Shader::ShaderPtrData ptr_data;
|
||||||
if (ptr_data == nullptr) { //the input is not contained in ShaderPtrData
|
if (!_glgsg->fetch_ptr_parameter(spec, ptr_data)) { //the input is not contained in ShaderPtrData
|
||||||
release_resources();
|
release_resources();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2119,18 +2119,18 @@ issue_parameters(int altered) {
|
|||||||
nassertd(spec._dim[1] > 0) continue;
|
nassertd(spec._dim[1] > 0) continue;
|
||||||
|
|
||||||
GLint p = spec._id._seqno;
|
GLint p = spec._id._seqno;
|
||||||
int array_size = min(spec._dim[0], (int)ptr_data->_size / spec._dim[1]);
|
int array_size = min(spec._dim[0], (int)ptr_data._size / spec._dim[1]);
|
||||||
switch (spec._type) {
|
switch (spec._type) {
|
||||||
case Shader::SPT_float:
|
case Shader::SPT_float:
|
||||||
{
|
{
|
||||||
float *data = nullptr;
|
float *data = nullptr;
|
||||||
|
|
||||||
switch (ptr_data->_type) {
|
switch (ptr_data._type) {
|
||||||
case Shader::SPT_int:
|
case Shader::SPT_int:
|
||||||
// Convert int data to float data.
|
// Convert int data to float data.
|
||||||
data = (float*) alloca(sizeof(float) * array_size * spec._dim[1]);
|
data = (float*) alloca(sizeof(float) * array_size * spec._dim[1]);
|
||||||
for (int i = 0; i < (array_size * spec._dim[1]); ++i) {
|
for (int i = 0; i < (array_size * spec._dim[1]); ++i) {
|
||||||
data[i] = (float)(((int*)ptr_data->_ptr)[i]);
|
data[i] = (float)(((int*)ptr_data._ptr)[i]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -2138,7 +2138,7 @@ issue_parameters(int altered) {
|
|||||||
// Convert unsigned int data to float data.
|
// Convert unsigned int data to float data.
|
||||||
data = (float*) alloca(sizeof(float) * array_size * spec._dim[1]);
|
data = (float*) alloca(sizeof(float) * array_size * spec._dim[1]);
|
||||||
for (int i = 0; i < (array_size * spec._dim[1]); ++i) {
|
for (int i = 0; i < (array_size * spec._dim[1]); ++i) {
|
||||||
data[i] = (float)(((unsigned int*)ptr_data->_ptr)[i]);
|
data[i] = (float)(((unsigned int*)ptr_data._ptr)[i]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -2146,12 +2146,12 @@ issue_parameters(int altered) {
|
|||||||
// Downgrade double data to float data.
|
// Downgrade double data to float data.
|
||||||
data = (float*) alloca(sizeof(float) * array_size * spec._dim[1]);
|
data = (float*) alloca(sizeof(float) * array_size * spec._dim[1]);
|
||||||
for (int i = 0; i < (array_size * spec._dim[1]); ++i) {
|
for (int i = 0; i < (array_size * spec._dim[1]); ++i) {
|
||||||
data[i] = (float)(((double*)ptr_data->_ptr)[i]);
|
data[i] = (float)(((double*)ptr_data._ptr)[i]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Shader::SPT_float:
|
case Shader::SPT_float:
|
||||||
data = (float*)ptr_data->_ptr;
|
data = (float*)ptr_data._ptr;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -2171,8 +2171,8 @@ issue_parameters(int altered) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Shader::SPT_int:
|
case Shader::SPT_int:
|
||||||
if (ptr_data->_type != Shader::SPT_int &&
|
if (ptr_data._type != Shader::SPT_int &&
|
||||||
ptr_data->_type != Shader::SPT_uint) {
|
ptr_data._type != Shader::SPT_uint) {
|
||||||
GLCAT.error()
|
GLCAT.error()
|
||||||
<< "Cannot pass floating-point data to integer shader input '" << spec._id._name << "'\n";
|
<< "Cannot pass floating-point data to integer shader input '" << spec._id._name << "'\n";
|
||||||
|
|
||||||
@ -2183,18 +2183,18 @@ issue_parameters(int altered) {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
switch (spec._dim[1]) {
|
switch (spec._dim[1]) {
|
||||||
case 1: _glgsg->_glUniform1iv(p, array_size, (int*)ptr_data->_ptr); continue;
|
case 1: _glgsg->_glUniform1iv(p, array_size, (int*)ptr_data._ptr); continue;
|
||||||
case 2: _glgsg->_glUniform2iv(p, array_size, (int*)ptr_data->_ptr); continue;
|
case 2: _glgsg->_glUniform2iv(p, array_size, (int*)ptr_data._ptr); continue;
|
||||||
case 3: _glgsg->_glUniform3iv(p, array_size, (int*)ptr_data->_ptr); continue;
|
case 3: _glgsg->_glUniform3iv(p, array_size, (int*)ptr_data._ptr); continue;
|
||||||
case 4: _glgsg->_glUniform4iv(p, array_size, (int*)ptr_data->_ptr); continue;
|
case 4: _glgsg->_glUniform4iv(p, array_size, (int*)ptr_data._ptr); continue;
|
||||||
}
|
}
|
||||||
nassertd(false) continue;
|
nassertd(false) continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Shader::SPT_uint:
|
case Shader::SPT_uint:
|
||||||
if (ptr_data->_type != Shader::SPT_uint &&
|
if (ptr_data._type != Shader::SPT_uint &&
|
||||||
ptr_data->_type != Shader::SPT_int) {
|
ptr_data._type != Shader::SPT_int) {
|
||||||
GLCAT.error()
|
GLCAT.error()
|
||||||
<< "Cannot pass floating-point data to integer shader input '" << spec._id._name << "'\n";
|
<< "Cannot pass floating-point data to integer shader input '" << spec._id._name << "'\n";
|
||||||
|
|
||||||
@ -2205,10 +2205,10 @@ issue_parameters(int altered) {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
switch (spec._dim[1]) {
|
switch (spec._dim[1]) {
|
||||||
case 1: _glgsg->_glUniform1uiv(p, array_size, (GLuint *)ptr_data->_ptr); continue;
|
case 1: _glgsg->_glUniform1uiv(p, array_size, (GLuint *)ptr_data._ptr); continue;
|
||||||
case 2: _glgsg->_glUniform2uiv(p, array_size, (GLuint *)ptr_data->_ptr); continue;
|
case 2: _glgsg->_glUniform2uiv(p, array_size, (GLuint *)ptr_data._ptr); continue;
|
||||||
case 3: _glgsg->_glUniform3uiv(p, array_size, (GLuint *)ptr_data->_ptr); continue;
|
case 3: _glgsg->_glUniform3uiv(p, array_size, (GLuint *)ptr_data._ptr); continue;
|
||||||
case 4: _glgsg->_glUniform4uiv(p, array_size, (GLuint *)ptr_data->_ptr); continue;
|
case 4: _glgsg->_glUniform4uiv(p, array_size, (GLuint *)ptr_data._ptr); continue;
|
||||||
}
|
}
|
||||||
nassertd(false) continue;
|
nassertd(false) continue;
|
||||||
}
|
}
|
||||||
|
@ -422,6 +422,57 @@ get_shader_input_ptr(const InternalName *id) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the ShaderInput as a ShaderPtrData struct. Assertion fails if
|
||||||
|
* there is none. or if it is not a PTA(double/float)
|
||||||
|
*/
|
||||||
|
bool ShaderAttrib::
|
||||||
|
get_shader_input_ptr(const InternalName *id, Shader::ShaderPtrData &data) const {
|
||||||
|
Inputs::const_iterator i = _inputs.find(id);
|
||||||
|
if (i != _inputs.end()) {
|
||||||
|
const ShaderInput &p = (*i).second;
|
||||||
|
if (p.get_value_type() == ShaderInput::M_numeric ||
|
||||||
|
p.get_value_type() == ShaderInput::M_vector) {
|
||||||
|
|
||||||
|
data = p.get_ptr();
|
||||||
|
return (data._ptr != nullptr);
|
||||||
|
}
|
||||||
|
if (p.get_value_type() == ShaderInput::M_param) {
|
||||||
|
// Temporary solution until the new param system
|
||||||
|
TypedWritableReferenceCount *param = p.get_value();
|
||||||
|
if (param != nullptr) {
|
||||||
|
if (param->is_of_type(ParamVecBase4f::get_class_type())) {
|
||||||
|
data._ptr = (void *)((const ParamVecBase4f *)param)->get_value().get_data();
|
||||||
|
data._size = 4;
|
||||||
|
data._type = Shader::SPT_float;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (param->is_of_type(ParamVecBase4i::get_class_type())) {
|
||||||
|
data._ptr = (void *)((const ParamVecBase4i *)param)->get_value().get_data();
|
||||||
|
data._size = 4;
|
||||||
|
data._type = Shader::SPT_int;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (param->is_of_type(ParamVecBase4d::get_class_type())) {
|
||||||
|
data._ptr = (void *)((const ParamVecBase4d *)param)->get_value().get_data();
|
||||||
|
data._size = 4;
|
||||||
|
data._type = Shader::SPT_float;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ostringstream strm;
|
||||||
|
strm << "Shader input " << id->get_name() << " was given an incompatible parameter type.\n";
|
||||||
|
nassert_raise(strm.str());
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
ostringstream strm;
|
||||||
|
strm << "Shader input " << id->get_name() << " is not present.\n";
|
||||||
|
nassert_raise(strm.str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the ShaderInput as a texture. Assertion fails if there is none, or
|
* Returns the ShaderInput as a texture. Assertion fails if there is none, or
|
||||||
* if it is not a texture.
|
* if it is not a texture.
|
||||||
|
@ -119,6 +119,7 @@ PUBLISHED:
|
|||||||
LVecBase4 get_shader_input_vector(InternalName *id) const;
|
LVecBase4 get_shader_input_vector(InternalName *id) const;
|
||||||
Texture *get_shader_input_texture(const InternalName *id, SamplerState *sampler=nullptr) const;
|
Texture *get_shader_input_texture(const InternalName *id, SamplerState *sampler=nullptr) const;
|
||||||
const Shader::ShaderPtrData *get_shader_input_ptr(const InternalName *id) const;
|
const Shader::ShaderPtrData *get_shader_input_ptr(const InternalName *id) const;
|
||||||
|
bool get_shader_input_ptr(const InternalName *id, Shader::ShaderPtrData &data) const;
|
||||||
const LMatrix4 &get_shader_input_matrix(const InternalName *id, LMatrix4 &matrix) const;
|
const LMatrix4 &get_shader_input_matrix(const InternalName *id, LMatrix4 &matrix) const;
|
||||||
ShaderBuffer *get_shader_input_buffer(const InternalName *id) const;
|
ShaderBuffer *get_shader_input_buffer(const InternalName *id) const;
|
||||||
|
|
||||||
|
@ -294,6 +294,36 @@ def test_glsl_pta_mat4(gsg):
|
|||||||
run_glsl_test(gsg, code, preamble, {'pta': pta})
|
run_glsl_test(gsg, code, preamble, {'pta': pta})
|
||||||
|
|
||||||
|
|
||||||
|
def test_glsl_param_vec4(gsg):
|
||||||
|
param = core.ParamVecBase4((0, 1, 2, 3))
|
||||||
|
|
||||||
|
preamble = """
|
||||||
|
uniform vec4 param;
|
||||||
|
"""
|
||||||
|
code = """
|
||||||
|
assert(param.x == 0.0);
|
||||||
|
assert(param.y == 1.0);
|
||||||
|
assert(param.z == 2.0);
|
||||||
|
assert(param.w == 3.0);
|
||||||
|
"""
|
||||||
|
run_glsl_test(gsg, code, preamble, {'param': param})
|
||||||
|
|
||||||
|
|
||||||
|
def test_glsl_param_ivec4(gsg):
|
||||||
|
param = core.ParamVecBase4i((0, 1, 2, 3))
|
||||||
|
|
||||||
|
preamble = """
|
||||||
|
uniform ivec4 param;
|
||||||
|
"""
|
||||||
|
code = """
|
||||||
|
assert(param.x == 0);
|
||||||
|
assert(param.y == 1);
|
||||||
|
assert(param.z == 2);
|
||||||
|
assert(param.w == 3);
|
||||||
|
"""
|
||||||
|
run_glsl_test(gsg, code, preamble, {'param': param})
|
||||||
|
|
||||||
|
|
||||||
def test_glsl_write_extract_image_buffer(gsg):
|
def test_glsl_write_extract_image_buffer(gsg):
|
||||||
# Tests that we can write to a buffer texture on the GPU, and then extract
|
# Tests that we can write to a buffer texture on the GPU, and then extract
|
||||||
# the data on the CPU. We test two textures since there was in the past a
|
# the data on the CPU. We test two textures since there was in the past a
|
||||||
|
Loading…
x
Reference in New Issue
Block a user