]> git.tdb.fi Git - libs/gl.git/blob - source/core/pipelinestate.cpp
Unify handling of shader resources in PipelineState
[libs/gl.git] / source / core / pipelinestate.cpp
1 #include <stdexcept>
2 #include <msp/core/algorithm.h>
3 #include "error.h"
4 #include "pipelinestate.h"
5 #include "uniformblock.h"
6
7 using namespace std;
8
9 namespace Msp {
10 namespace GL {
11
12 template<typename T>
13 void PipelineState::set(T &target, const T &value, unsigned flag)
14 {
15         if(value!=target)
16         {
17                 target = value;
18                 changes |= flag;
19         }
20 }
21
22 void PipelineState::set_framebuffer(const Framebuffer *f)
23 {
24         set(framebuffer, f, FRAMEBUFFER);
25 }
26
27 void PipelineState::set_viewport(const Rect &v)
28 {
29         set(viewport, v, VIEWPORT);
30 }
31
32 void PipelineState::set_scissor(const Rect &s)
33 {
34         set(scissor, s, SCISSOR);
35 }
36
37 void PipelineState::set_shader_program(const Program *p)
38 {
39         set(shprog, p, SHPROG);
40 }
41
42 void PipelineState::set_uniform_block(int binding, const UniformBlock *block)
43 {
44         auto i = lower_bound_member(resources, binding, &BoundResource::binding);
45         if(i==resources.end() || i->binding!=binding)
46                 i = resources.insert(i, BoundResource(binding));
47
48         ResourceType type = (block ? UNIFORM_BLOCK : NO_RESOURCE);
49         const Buffer *buffer = (block ? block->get_buffer() : 0);
50         if(i->type!=type || block!=i->block || buffer!=i->buffer || binding<0)
51         {
52                 i->type = type;
53                 i->block = block;
54                 i->buffer = buffer;
55                 i->changed = true;
56                 i->used = block;
57                 changes |= RESOURCES;
58         }
59 }
60
61 void PipelineState::set_texture(unsigned binding, const Texture *tex, const Sampler *samp)
62 {
63         set_texture(binding, tex, -1, samp);
64 }
65
66 void PipelineState::set_texture(unsigned binding, const Texture *tex, int level, const Sampler *samp)
67 {
68         if((tex!=0)!=(samp!=0))
69                 throw invalid_argument("PipelineState::set_texture");
70         if(level>=0 && !can_bind_tex_level(level))
71                 throw invalid_operation("PipelineState::set_texture");
72
73         auto i = lower_bound_member(resources, static_cast<int>(binding), &BoundResource::binding);
74         if(i==resources.end() || i->binding!=static_cast<int>(binding))
75                 i = resources.insert(i, BoundResource(binding));
76
77         ResourceType type = (tex ? TEXTURE : NO_RESOURCE);
78         if(i->type!=type || tex!=i->texture || level!=i->mip_level || samp!=i->sampler)
79         {
80                 i->type = type;
81                 i->texture = tex;
82                 i->sampler = samp;
83                 i->mip_level = level;
84                 i->changed = true;
85                 i->used = (tex && samp);
86                 changes |= RESOURCES;
87         }
88 }
89
90 void PipelineState::set_vertex_setup(const VertexSetup *s)
91 {
92         set(vertex_setup, s, VERTEX_SETUP);
93 }
94
95 void PipelineState::set_primitive_type(PrimitiveType t)
96 {
97         set(primitive_type, t, PRIMITIVE_TYPE);
98 }
99
100 void PipelineState::set_front_face(FaceWinding w)
101 {
102         set(front_face, w, FACE_CULL);
103 }
104
105 void PipelineState::set_face_cull(CullMode c)
106 {
107         set(face_cull, c, FACE_CULL);
108 }
109
110 void PipelineState::set_depth_test(const DepthTest &dt)
111 {
112         set(depth_test, dt, DEPTH_TEST);
113 }
114
115 void PipelineState::set_stencil_test(const StencilTest &st)
116 {
117         set(stencil_test, st, STENCIL_TEST);
118 }
119
120 void PipelineState::set_blend(const Blend &b)
121 {
122         set(blend, b, BLEND);
123 }
124
125 } // namespace GL
126 } // namespace Msp