2 #include <msp/core/algorithm.h>
3 #include <msp/io/print.h>
5 #include "pipelinestate.h"
7 #include "uniformblock.h"
15 void PipelineState::set(T &target, const T &value, unsigned flag)
24 void PipelineState::set_framebuffer(const Framebuffer *f)
26 set(framebuffer, f, FRAMEBUFFER);
29 void PipelineState::set_viewport(const Rect &v)
31 set(viewport, v, VIEWPORT);
34 void PipelineState::set_scissor(const Rect &s)
36 set(scissor, s, SCISSOR);
39 void PipelineState::set_shader_program(const Program *p)
41 set(shprog, p, SHPROG);
44 void PipelineState::set_uniform_block(int binding, const UniformBlock *block)
46 auto i = lower_bound_member(resources, binding, &BoundResource::binding);
47 if(i==resources.end() || i->binding!=binding)
48 i = resources.insert(i, BoundResource(binding));
50 ResourceType type = (block ? UNIFORM_BLOCK : NO_RESOURCE);
51 const Buffer *buffer = (block ? block->get_buffer() : 0);
52 if(i->type!=type || block!=i->block || buffer!=i->buffer || binding<0)
63 void PipelineState::set_texture(unsigned binding, const Texture *tex, const Sampler *samp)
65 set_texture(binding, tex, -1, samp);
68 void PipelineState::set_texture(unsigned binding, const Texture *tex, int level, const Sampler *samp)
70 if((tex!=0)!=(samp!=0))
71 throw invalid_argument("PipelineState::set_texture");
72 if(level>=0 && !can_bind_tex_level(level))
73 throw invalid_operation("PipelineState::set_texture");
75 set_texture_resource(binding, tex, level, samp);
78 void PipelineState::set_storage_texture(unsigned binding, const Texture *tex)
80 set_texture_resource(binding, tex, 0, 0);
83 void PipelineState::set_texture_resource(unsigned binding, const Texture *tex, int level, const Sampler *samp)
85 auto i = lower_bound_member(resources, static_cast<int>(binding), &BoundResource::binding);
86 if(i==resources.end() || i->binding!=static_cast<int>(binding))
87 i = resources.insert(i, BoundResource(binding));
89 ResourceType type = (tex ? samp ? SAMPLED_TEXTURE : STORAGE_TEXTURE : NO_RESOURCE);
90 if(i->type!=type || tex!=i->texture || level!=i->mip_level || samp!=i->sampler)
102 void PipelineState::set_vertex_setup(const VertexSetup *s)
104 set(vertex_setup, s, VERTEX_SETUP);
107 void PipelineState::set_primitive_type(PrimitiveType t)
109 set(primitive_type, t, PRIMITIVE_TYPE);
112 void PipelineState::set_patch_size(unsigned s)
114 set(patch_size, s, PATCH_SIZE);
117 void PipelineState::set_front_face(FaceWinding w)
119 set(front_face, w, FACE_CULL);
122 void PipelineState::set_face_cull(CullMode c)
124 set(face_cull, c, FACE_CULL);
127 void PipelineState::set_depth_test(const DepthTest &dt)
129 set(depth_test, dt, DEPTH_TEST);
132 void PipelineState::set_stencil_test(const StencilTest &st)
134 set(stencil_test, st, STENCIL_TEST);
137 void PipelineState::set_blend(const Blend &b)
139 set(blend, b, BLEND);
142 void PipelineState::check_bound_resources() const
147 for(const ReflectData::UniformBlockInfo &b: shprog->get_uniform_blocks())
148 if(b.bind_point!=ReflectData::DEFAULT_BLOCK)
150 auto i = lower_bound_member(resources, b.bind_point, &PipelineState::BoundResource::binding);
151 if(i==resources.end() || i->binding!=b.bind_point)
152 IO::print(IO::cerr, "Warning: No resource present for uniform block binding %d:%d (%s)\n", b.bind_point>>20, b.bind_point&0xFFFFF, b.name);
155 for(const ReflectData::UniformInfo &u: shprog->get_uniforms())
156 if(u.binding>=0 && is_image(u.type))
158 auto i = lower_bound_member(resources, u.binding, &PipelineState::BoundResource::binding);
159 if(i==resources.end() || i->binding!=u.binding)
160 IO::print(IO::cerr, "Warning: No resource present for texture binding %d:%d (%s)\n", u.binding>>20, u.binding&0xFFFFF, u.name);