for(VariableDeclaration *b: unbound_blocks)
bind_uniform(b->layout, b->block_declaration->block_name, features.uniform_binding_range);
for(VariableDeclaration *t: unbound_textures)
- bind_uniform(t->layout, t->name, features.texture_binding_range);
+ {
+ const TypeDeclaration *base_type = get_ultimate_base_type(t->type_declaration);
+ unsigned range = (static_cast<const ImageTypeDeclaration *>(base_type)->sampled ?
+ features.texture_binding_range : features.storage_texture_binding_range);
+ bind_uniform(t->layout, t->name, range);
+ }
}
void LocationAllocator::apply(Stage &stage)
bool LocationAllocator::visit_uniform(const string &name, RefPtr<Layout> &layout)
{
- int desc_set = 0;
+ int desc_set = get_layout_value(layout.get(), "set");
int bind_point = get_layout_value(layout.get(), "binding");
if(features.target_api==VULKAN)
{
- desc_set = get_layout_value(layout.get(), "set");
if(desc_set<0 && bind_point>=0)
{
desc_set = 0;
if(desc_set>=0)
uniforms[name].desc_set = desc_set;
}
+ else if(desc_set>=0 && bind_point<0)
+ {
+ auto i = find_member(layout->qualifiers, string("set"), &Layout::Qualifier::name);
+ layout->qualifiers.erase(i);
+ }
if(bind_point>=0)
{
stage.content.visit(*this);
}
+void DepthRangeConverter::visit(VariableReference &var)
+{
+ const StructDeclaration *strct = dynamic_cast<const StructDeclaration *>(var.type);
+ r_gl_pervertex = (strct && strct->block_name=="gl_PerVertex");
+}
+
+void DepthRangeConverter::visit(MemberAccess &memacc)
+{
+ r_gl_pervertex = false;
+ memacc.left->visit(*this);
+ r_gl_position = (r_gl_pervertex && memacc.member=="gl_Position");
+}
+
+void DepthRangeConverter::visit(Swizzle &swiz)
+{
+ r_gl_position = false;
+ swiz.left->visit(*this);
+ if(assignment_target && r_gl_position && swiz.count==1 && swiz.components[0]==2)
+ r_position_z_assigned = true;
+}
+
+void DepthRangeConverter::visit(Assignment &assign)
+{
+ {
+ SetFlag set_target(assignment_target);
+ assign.left->visit(*this);
+ }
+ assign.right->visit(*this);
+}
+
void DepthRangeConverter::visit(FunctionDeclaration &func)
{
- if(func.definition==&func && func.name=="main")
+ r_position_z_assigned = false;
+ TraversingVisitor::visit(func);
+
+ if(func.definition==&func && func.name=="main" && !r_position_z_assigned)
{
VariableReference *position = new VariableReference;
position->name = "gl_Position";
bool StructuralFeatureConverter::supports_stage(Stage::Type st) const
{
- if(st==Stage::GEOMETRY)
+ if(st==Stage::TESS_CONTROL || st==Stage::TESS_EVAL)
+ {
+ if(features.target_api==OPENGL_ES)
+ return check_version(Version(3, 20));
+ else
+ return check_version(Version(4, 0));
+ }
+ else if(st==Stage::GEOMETRY)
{
- if(features.target_api==VULKAN)
- return true;
- else if(features.target_api==OPENGL_ES)
+ if(features.target_api==OPENGL_ES)
return check_version(Version(3, 20));
else
return check_version(Version(1, 50));
}
+ else if(st==Stage::COMPUTE)
+ {
+ if(features.target_api==OPENGL_ES)
+ return check_version(Version(3, 10));
+ else
+ return check_version(Version(4, 30));
+ }
else
return true;
}
bool StructuralFeatureConverter::supports_unified_interface_syntax() const
{
- if(features.target_api==VULKAN)
- return true;
- else if(features.target_api==OPENGL_ES)
+ if(features.target_api==OPENGL_ES)
return check_version(Version(3, 0));
else
return check_version(Version(1, 30));
bool StructuralFeatureConverter::supports_unified_sampling_functions() const
{
- if(features.target_api==VULKAN)
- return true;
- else if(features.target_api==OPENGL_ES)
+ if(features.target_api==OPENGL_ES)
return check_version(Version(3, 0));
else
return check_version(Version(1, 30));
bool StructuralFeatureConverter::supports_interface_blocks(const string &iface) const
{
- if(features.target_api==VULKAN)
- return true;
- else if(features.target_api==OPENGL_ES)
+ if(features.target_api==OPENGL_ES)
{
if(iface=="uniform")
return check_version(Version(3, 0));
bool QualifierConverter::supports_interface_layouts() const
{
- if(features.target_api==VULKAN)
- return true;
- else if(features.target_api==OPENGL_ES)
+ if(features.target_api==OPENGL_ES)
return check_version(Version(3, 0));
else if(check_version(Version(3, 30)))
return true;
bool QualifierConverter::supports_stage_interface_layouts() const
{
- if(features.target_api==VULKAN)
- return true;
- else if(features.target_api==OPENGL_ES)
+ if(features.target_api==OPENGL_ES)
return check_version(Version(3, 10));
else if(check_version(Version(4, 10)))
return true;
bool QualifierConverter::supports_centroid_sampling() const
{
- if(features.target_api==VULKAN)
- return true;
- else if(features.target_api==OPENGL_ES)
+ if(features.target_api==OPENGL_ES)
return check_version(Version(3, 0));
else if(check_version(Version(1, 20)))
return true;
bool QualifierConverter::supports_sample_sampling() const
{
- if(features.target_api==VULKAN)
- return true;
- else if(features.target_api==OPENGL_ES)
+ if(features.target_api==OPENGL_ES)
return check_version(Version(3, 20));
else if(check_version(Version(4, 0)))
return true;
bool QualifierConverter::supports_uniform_location() const
{
- if(features.target_api==VULKAN)
- return false;
- else if(features.target_api==OPENGL_ES)
+ if(features.target_api==OPENGL_ES)
return check_version(Version(3, 10));
else if(check_version(Version(4, 30)))
return true;
bool QualifierConverter::supports_binding() const
{
- if(features.target_api==VULKAN)
- return true;
- else if(features.target_api==OPENGL_ES)
+ if(features.target_api==OPENGL_ES)
return check_version(Version(3, 10));
else
return check_version(Version(4, 20));
bool QualifierConverter::supports_interface_block_location() const
{
- if(features.target_api==VULKAN)
- return true;
- else if(features.target_api==OPENGL_ES)
+ if(features.target_api==OPENGL_ES)
return check_version(Version(3, 20));
else if(check_version(Version(4, 40)))
return true;