]> git.tdb.fi Git - libs/gl.git/blob - source/core/pipelinestate.cpp
0769d441a83a3de178f932af44142bf2b81c1f73
[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         set_texture_resource(binding, tex, level, samp);
74 }
75
76 void PipelineState::set_storage_texture(unsigned binding, const Texture *tex)
77 {
78         set_texture_resource(binding, tex, 0, 0);
79 }
80
81 void PipelineState::set_texture_resource(unsigned binding, const Texture *tex, int level, const Sampler *samp)
82 {
83         auto i = lower_bound_member(resources, static_cast<int>(binding), &BoundResource::binding);
84         if(i==resources.end() || i->binding!=static_cast<int>(binding))
85                 i = resources.insert(i, BoundResource(binding));
86
87         ResourceType type = (tex ? samp ? SAMPLED_TEXTURE : STORAGE_TEXTURE : NO_RESOURCE);
88         if(i->type!=type || tex!=i->texture || level!=i->mip_level || samp!=i->sampler)
89         {
90                 i->type = type;
91                 i->texture = tex;
92                 i->sampler = samp;
93                 i->mip_level = level;
94                 i->changed = true;
95                 i->used = tex;
96                 changes |= RESOURCES;
97         }
98 }
99
100 void PipelineState::set_vertex_setup(const VertexSetup *s)
101 {
102         set(vertex_setup, s, VERTEX_SETUP);
103 }
104
105 void PipelineState::set_primitive_type(PrimitiveType t)
106 {
107         set(primitive_type, t, PRIMITIVE_TYPE);
108 }
109
110 void PipelineState::set_patch_size(unsigned s)
111 {
112         set(patch_size, s, PATCH_SIZE);
113 }
114
115 void PipelineState::set_front_face(FaceWinding w)
116 {
117         set(front_face, w, FACE_CULL);
118 }
119
120 void PipelineState::set_face_cull(CullMode c)
121 {
122         set(face_cull, c, FACE_CULL);
123 }
124
125 void PipelineState::set_depth_test(const DepthTest &dt)
126 {
127         set(depth_test, dt, DEPTH_TEST);
128 }
129
130 void PipelineState::set_stencil_test(const StencilTest &st)
131 {
132         set(stencil_test, st, STENCIL_TEST);
133 }
134
135 void PipelineState::set_blend(const Blend &b)
136 {
137         set(blend, b, BLEND);
138 }
139
140 } // namespace GL
141 } // namespace Msp