1use rs_ctypes::*;
31use gl::types::*;
32use crate::*;
33use crate::rs_math3d::*;
34use super::readback::*;
35
36use std::collections::{VecDeque};
37use core::ops::{Index};
38use core::sync::atomic::*;
39
40fn color4b_to_color4f(col: Color4b) -> Vec4f {
41 let r = col.x as f32 / 255.0;
42 let g = col.y as f32 / 255.0;
43 let b = col.z as f32 / 255.0;
44 let a = col.w as f32 / 255.0;
45 Vec4f::new(r, g, b, a)
46}
47
48unsafe fn alloc_string<'a>(size: usize) -> &'a mut str {
49 let l = std::alloc::Layout::array::<u8>(size as usize).unwrap();
50 let sptr = std::alloc::alloc(l);
51 let sl = std::slice::from_raw_parts_mut(sptr, size as usize);
52 std::str::from_utf8_unchecked_mut(sl)
53}
54
55unsafe fn free_string<'a>(s: &mut str, size: usize) {
56 let l = std::alloc::Layout::array::<u8>(size as usize).unwrap();
57 std::alloc::dealloc(s.as_mut_ptr(), l);
58}
59
60pub struct GLProgram {
61 prog_id : GLuint,
62}
63
64impl Drop for GLProgram {
65 fn drop(&mut self) {
66 unsafe { gl::DeleteProgram(self.prog_id) };
67 }
68}
69
70trait GLUniformBlock {
71 fn setup(&self);
72}
73
74trait GLVertexFormat {
75 fn gl_elem_count(&self) -> GLuint;
76 fn gl_elem_type(&self) -> GLenum;
77 fn gl_is_normalized(&self) -> GLboolean;
78}
79
80impl GLVertexFormat for VertexFormat {
81 fn gl_elem_count(&self) -> GLuint {
82 match self {
83 VertexFormat::Byte => 1,
84 VertexFormat::Byte2 => 2,
85 VertexFormat::Byte3 => 3,
86 VertexFormat::Byte4 => 4,
87
88 VertexFormat::SByte => 1,
89 VertexFormat::SByte2 => 2,
90 VertexFormat::SByte3 => 3,
91 VertexFormat::SByte4 => 4,
92
93 VertexFormat::Int => 1,
94 VertexFormat::Int2 => 2,
95 VertexFormat::Int3 => 3,
96 VertexFormat::Int4 => 4,
97
98 VertexFormat::UInt => 1,
99 VertexFormat::UInt2 => 2,
100 VertexFormat::UInt3 => 3,
101 VertexFormat::UInt4 => 4,
102
103 VertexFormat::Short => 1,
104 VertexFormat::Short2 => 2,
105 VertexFormat::Short3 => 3,
106 VertexFormat::Short4 => 4,
107
108 VertexFormat::Float => 1,
109 VertexFormat::Float2 => 2,
110 VertexFormat::Float3 => 3,
111 VertexFormat::Float4 => 4,
112
113 VertexFormat::Float2x2 => 4,
114 VertexFormat::Float3x3 => 9,
115 VertexFormat::Float4x4 => 16,
116 }
117 }
118
119 fn gl_elem_type(&self) -> GLenum {
120 match self {
121 VertexFormat::Byte => gl::UNSIGNED_BYTE,
122 VertexFormat::Byte2 => gl::UNSIGNED_BYTE,
123 VertexFormat::Byte3 => gl::UNSIGNED_BYTE,
124 VertexFormat::Byte4 => gl::UNSIGNED_BYTE,
125
126 VertexFormat::SByte => gl::BYTE,
127 VertexFormat::SByte2 => gl::BYTE,
128 VertexFormat::SByte3 => gl::BYTE,
129 VertexFormat::SByte4 => gl::BYTE,
130
131 VertexFormat::Int => gl::INT,
132 VertexFormat::Int2 => gl::INT,
133 VertexFormat::Int3 => gl::INT,
134 VertexFormat::Int4 => gl::INT,
135
136 VertexFormat::UInt => gl::UNSIGNED_INT,
137 VertexFormat::UInt2 => gl::UNSIGNED_INT,
138 VertexFormat::UInt3 => gl::UNSIGNED_INT,
139 VertexFormat::UInt4 => gl::UNSIGNED_INT,
140
141 VertexFormat::Short => gl::SHORT,
142 VertexFormat::Short2 => gl::SHORT,
143 VertexFormat::Short3 => gl::SHORT,
144 VertexFormat::Short4 => gl::SHORT,
145
146 VertexFormat::Float => gl::FLOAT,
147 VertexFormat::Float2 => gl::FLOAT,
148 VertexFormat::Float3 => gl::FLOAT,
149 VertexFormat::Float4 => gl::FLOAT,
150
151 VertexFormat::Float2x2 => gl::FLOAT,
152 VertexFormat::Float3x3 => gl::FLOAT,
153 VertexFormat::Float4x4 => gl::FLOAT,
154 }
155 }
156
157 fn gl_is_normalized(&self) -> GLboolean {
158 let r = match self {
159 VertexFormat::Byte => true,
160 VertexFormat::Byte2 => true,
161 VertexFormat::Byte3 => true,
162 VertexFormat::Byte4 => true,
163
164 VertexFormat::SByte => true,
165 VertexFormat::SByte2 => true,
166 VertexFormat::SByte3 => true,
167 VertexFormat::SByte4 => true,
168
169 VertexFormat::Int => false,
170 VertexFormat::Int2 => false,
171 VertexFormat::Int3 => false,
172 VertexFormat::Int4 => false,
173
174 VertexFormat::UInt => false,
175 VertexFormat::UInt2 => false,
176 VertexFormat::UInt3 => false,
177 VertexFormat::UInt4 => false,
178
179 VertexFormat::Short => false,
180 VertexFormat::Short2 => false,
181 VertexFormat::Short3 => false,
182 VertexFormat::Short4 => false,
183
184 VertexFormat::Float => false,
185 VertexFormat::Float2 => false,
186 VertexFormat::Float3 => false,
187 VertexFormat::Float4 => false,
188
189 VertexFormat::Float2x2 => false,
190 VertexFormat::Float3x3 => false,
191 VertexFormat::Float4x4 => false,
192 };
193 r as GLboolean
194 }
195}
196
197fn uniform_ptr_to_slice<'a, T>(ptr: *const c_void, offset: usize, count: usize) -> &'a [T] {
198 let cptr = ptr as *const u8;
199 let _cptr = unsafe { cptr.offset(offset as isize) };
200 let tptr = _cptr as *const T;
201 unsafe { core::slice::from_raw_parts(tptr, count) }
202}
203
204fn setup_uniforms(uniforms: *const c_void, data_desc_layout: &[UniformDataDesc], prg_desc_layout: &[(String, GLuint)]) {
205 unsafe {
206 for i in 0..data_desc_layout.len() {
207 let offset = data_desc_layout[i].offset();
208 let location = prg_desc_layout[i].1 as GLint;
209 match &data_desc_layout[i].desc().format() {
210 UniformDataType::UInt => { let s : &[u32] = uniform_ptr_to_slice(uniforms, offset, 1); gl::Uniform1uiv(location, 1, s.as_ptr()); },
211 UniformDataType::UInt2=> { let s : &[u32] = uniform_ptr_to_slice(uniforms, offset, 2); gl::Uniform2uiv(location, 1, s.as_ptr()); },
212 UniformDataType::UInt3=> { let s : &[u32] = uniform_ptr_to_slice(uniforms, offset, 3); gl::Uniform3uiv(location, 1, s.as_ptr()); },
213 UniformDataType::UInt4=> { let s : &[u32] = uniform_ptr_to_slice(uniforms, offset, 4); gl::Uniform4uiv(location, 1, s.as_ptr()); },
214 UniformDataType::Int => { let s : &[i32] = uniform_ptr_to_slice(uniforms, offset, 1); gl::Uniform1iv(location, 1, s.as_ptr()); },
215 UniformDataType::Int2 => { let s : &[i32] = uniform_ptr_to_slice(uniforms, offset, 2); gl::Uniform2iv(location, 1, s.as_ptr()); },
216 UniformDataType::Int3 => { let s : &[i32] = uniform_ptr_to_slice(uniforms, offset, 3); gl::Uniform3iv(location, 1, s.as_ptr()); },
217 UniformDataType::Int4 => { let s : &[i32] = uniform_ptr_to_slice(uniforms, offset, 4); gl::Uniform4iv(location, 1, s.as_ptr()); },
218 UniformDataType::Float => { let s : &[f32] = uniform_ptr_to_slice(uniforms, offset, 1); gl::Uniform1fv(location, 1, s.as_ptr()); },
219 UniformDataType::Float2 => { let s : &[f32] = uniform_ptr_to_slice(uniforms, offset, 2); gl::Uniform2fv(location, 1, s.as_ptr()); },
220 UniformDataType::Float3 => { let s : &[f32] = uniform_ptr_to_slice(uniforms, offset, 3); gl::Uniform3fv(location, 1, s.as_ptr()); },
221 UniformDataType::Float4 => { let s : &[f32] = uniform_ptr_to_slice(uniforms, offset, 4); gl::Uniform4fv(location, 1, s.as_ptr()); },
222 UniformDataType::Float2x2 => { let s : &[f32] = uniform_ptr_to_slice(uniforms, offset, 4); gl::UniformMatrix2fv(location, 1, false as GLboolean, s.as_ptr()); },
223 UniformDataType::Float3x3 => { let s : &[f32] = uniform_ptr_to_slice(uniforms, offset, 9); gl::UniformMatrix3fv(location, 1, false as GLboolean, s.as_ptr()); },
224 UniformDataType::Float4x4 => { let s : &[f32] = uniform_ptr_to_slice(uniforms, offset, 16); gl::UniformMatrix4fv(location, 1, false as GLboolean, s.as_ptr()); },
225 }
226 }
227 }
228}
229
230struct GLDeviceBuffer {
231 gl_id : GLuint,
232 desc : DeviceBufferDesc,
233}
234
235impl Drop for GLDeviceBuffer {
236 fn drop(&mut self) {
237 unsafe { gl::DeleteBuffers(1, &self.gl_id as *const GLuint) };
238 }
239}
240
241struct GLTexture {
242 gl_id : GLuint,
243}
244
245impl Drop for GLTexture {
246 fn drop(&mut self) {
247 unsafe {
248 gl::DeleteTextures(1, &self.gl_id as *const GLuint);
249 }
250 }
251}
252
253struct GLRenderTarget {
254 gl_id : GLuint,
255}
256
257impl Drop for GLRenderTarget {
258 fn drop(&mut self) {
259 unsafe {
260 gl::DeleteRenderbuffers(1, &self.gl_id as *const GLuint);
261 }
262 }
263}
264
265trait GLPixelFormat {
266 fn gl_internal_format(&self) -> GLuint;
267 fn gl_format(&self) -> GLuint;
268 fn gl_elem_type(&self) -> GLenum;
269 fn gl_pixel_size(&self) -> usize;
270}
271
272impl GLPixelFormat for PixelFormat {
273 fn gl_internal_format(&self) -> GLenum {
274 match self {
275 PixelFormat::RGB8U => gl::RGB8UI,
276 PixelFormat::RGBA8U => gl::RGBA8UI,
277 PixelFormat::R8U => gl::R8UI,
278 PixelFormat::RGB32U => gl::RGB32UI,
279 PixelFormat::RGBA32U=> gl::RGBA32UI,
280 PixelFormat::R32U => gl::R32UI,
281
282 PixelFormat::RGB32F => gl::RGB32F,
283 PixelFormat::RGBA32F=> gl::RGBA32F,
284 PixelFormat::R32F => gl::R32F,
285
286 PixelFormat::D16 => gl::DEPTH_COMPONENT16,
287 PixelFormat::D32 => gl::DEPTH_COMPONENT32F,
288 PixelFormat::D24S8 => gl::DEPTH24_STENCIL8,
289 PixelFormat::D32S8 => gl::DEPTH32F_STENCIL8,
290
291 PixelFormat::RGB8(_) => gl::RGB,
292 PixelFormat::RGBA8(_) => gl::RGBA,
293 PixelFormat::R8(_) => gl::RED,
294 }
295 }
296
297 fn gl_format(&self) -> GLenum {
298 match self {
299 PixelFormat::RGB8U => gl::RGB_INTEGER,
300 PixelFormat::RGBA8U => gl::RGBA_INTEGER,
301 PixelFormat::R8U => gl::RED_INTEGER,
302 PixelFormat::RGB32U => gl::RGB_INTEGER,
303 PixelFormat::RGBA32U=> gl::RGBA_INTEGER,
304 PixelFormat::R32U => gl::RED_INTEGER,
305
306 PixelFormat::RGB32F => gl::RGB,
307 PixelFormat::RGBA32F=> gl::RGBA,
308 PixelFormat::R32F => gl::RED,
309
310 PixelFormat::D16 => gl::DEPTH_COMPONENT,
311 PixelFormat::D32 => gl::DEPTH_COMPONENT,
312 PixelFormat::D24S8 => gl::DEPTH_STENCIL,
313 PixelFormat::D32S8 => gl::DEPTH_STENCIL,
314
315 PixelFormat::RGB8(_) => gl::RGB,
316 PixelFormat::RGBA8(_) => gl::RGBA,
317 PixelFormat::R8(_) => gl::RED,
318 }
319 }
320
321 fn gl_elem_type(&self) -> GLenum {
322 match &self {
323 PixelFormat::RGB8U => gl::UNSIGNED_BYTE,
324 PixelFormat::RGBA8U => gl::UNSIGNED_BYTE,
325 PixelFormat::R8U => gl::UNSIGNED_BYTE,
326 PixelFormat::RGB32U => gl::UNSIGNED_INT,
327 PixelFormat::RGBA32U=> gl::UNSIGNED_INT,
328 PixelFormat::R32U => gl::UNSIGNED_INT,
329
330 PixelFormat::RGB32F => gl::FLOAT,
331 PixelFormat::RGBA32F=> gl::FLOAT,
332 PixelFormat::R32F => gl::FLOAT,
333
334 PixelFormat::D16 => gl::UNSIGNED_SHORT,
335 PixelFormat::D32 => gl::FLOAT,
336 PixelFormat::D24S8 => gl::UNSIGNED_INT_24_8,
337 PixelFormat::D32S8 => gl::FLOAT_32_UNSIGNED_INT_24_8_REV,
338
339 PixelFormat::RGB8(_) => gl::UNSIGNED_BYTE,
340 PixelFormat::RGBA8(_) => gl::UNSIGNED_BYTE,
341 PixelFormat::R8(_) => gl::UNSIGNED_BYTE,
342 }
343 }
344
345 fn gl_pixel_size(&self) -> usize {
346 match &self {
347 PixelFormat::RGB8U => 3,
348 PixelFormat::RGBA8U => 4,
349 PixelFormat::R8U => 1,
350 PixelFormat::RGB32U => 3 * 4,
351 PixelFormat::RGBA32U=> 4 * 4,
352 PixelFormat::R32U => 4,
353
354 PixelFormat::RGB32F => 3 * 4,
355 PixelFormat::RGBA32F=> 4 * 4,
356 PixelFormat::R32F => 4,
357
358 PixelFormat::D16 => 2,
359 PixelFormat::D32 => 4,
360 PixelFormat::D24S8 => 4,
361 PixelFormat::D32S8 => 5,
362
363 PixelFormat::RGB8(_) => 3,
364 PixelFormat::RGBA8(_) => 4,
365 PixelFormat::R8(_) => 1,
366 }
367 }
368}
369
370struct GLShader {
371 gl_id : GLuint,
372
373 vertex_attributes : Vec<Vec<(String, GLuint)>>,
374
375 vertex_uniforms : Vec<(String, GLuint)>,
376 vertex_surfaces : Vec<(String, GLuint)>,
377
378 pixel_uniforms : Vec<(String, GLuint)>,
379 pixel_surfaces : Vec<(String, GLuint)>,
380}
381
382impl Drop for GLShader {
383 fn drop(&mut self) {
384 unsafe { gl::DeleteProgram(self.gl_id) }
385 }
386}
387
388struct GLPipeline {
389 desc : PipelineDesc,
390}
391
392struct GLFrameBuffer {
393 gl_id : GLuint,
394 desc : FrameBufferDesc,
395}
396
397impl Drop for GLFrameBuffer {
398 fn drop(&mut self) {
399 unsafe {
400 gl::DeleteFramebuffers(1, &self.gl_id as *const GLuint)
401 }
402 }
403}
404
405trait GLBlendFactor {
406 fn gl_blend_factor(&self) -> GLenum;
407}
408
409impl GLBlendFactor for BlendFactor {
410 fn gl_blend_factor(&self) -> GLenum {
411 match self {
412 BlendFactor::Zero => gl::ZERO,
413 BlendFactor::One => gl::ONE,
414 BlendFactor::SrcColor => gl::SRC_COLOR,
415 BlendFactor::OneMinusSrcColor => gl::ONE_MINUS_SRC_COLOR,
416 BlendFactor::SrcAlpha => gl::SRC_ALPHA,
417 BlendFactor::OneMinusSrcAlpha => gl::ONE_MINUS_SRC_ALPHA,
418 BlendFactor::DstColor => gl::DST_COLOR,
419 BlendFactor::OneMinusDstColor => gl::ONE_MINUS_DST_COLOR,
420 BlendFactor::DstAlpha => gl::DST_ALPHA,
421 BlendFactor::OneMinusDstAlpha => gl::ONE_MINUS_DST_ALPHA,
422 BlendFactor::SrcAlphaSaturate => gl::SRC_ALPHA_SATURATE,
423 BlendFactor::ConstantColor => gl::CONSTANT_COLOR,
424 BlendFactor::OneMinusConstantColor => gl::ONE_MINUS_CONSTANT_COLOR,
425 BlendFactor::ConstantAlpha => gl::CONSTANT_ALPHA,
426 BlendFactor::OneMinusConstantAlpha => gl::ONE_MINUS_CONSTANT_ALPHA,
427 }
428 }
429}
430struct ResourceContainer<T> {
435 res : Vec<Option<T>>,
436 free_res : VecDeque<usize>,
437}
438
439impl<T> ResourceContainer<T> {
440 fn new() -> Self { Self { res: Vec::new(), free_res: VecDeque::new() } }
441
442 fn add(&mut self, t: T) -> usize {
443 match self.free_res.len() {
444 0 => {
445 let idx = self.res.len();
446 self.res.push(Some(t));
447 idx
448 },
449 _ => {
450 let idx = self.free_res.pop_front().unwrap();
451 self.res[idx] = Some(t);
452 idx
453 }
454 }
455 }
456
457 fn remove(&mut self, idx: usize) {
458 match self.res[idx].as_ref() {
459 Some(_) => {
460 self.res[idx] = None;
461 self.free_res.push_back(idx);
462 },
463 None => panic!("Deleting an already deleted object")
464 }
465 }
466}
467
468impl<T> Index<usize> for ResourceContainer<T> {
469 type Output = T;
470
471 fn index(&self, idx: usize) -> &Self::Output {
472 match &self.res[idx] {
473 Some(t) => &t,
474 None => panic!("Accessing invalid object index")
475 }
476 }
477}
478
479pub struct NullPayload {
480 size : usize,
481}
482
483impl Payload for NullPayload {
484 fn size(&self) -> usize { self.size }
485 fn ptr(&self) -> *const u8 { ::core::ptr::null() }
486}
487
488impl Drop for NullPayload {
489 fn drop(&mut self) {}
490}
491
492
493pub struct Gles3Driver {
497 device_buffers : ResourceContainer<GLDeviceBuffer>,
498 textures : ResourceContainer<GLTexture>,
499 render_targets : ResourceContainer<GLRenderTarget>,
500 shaders : ResourceContainer<GLShader>,
501 pipelines : ResourceContainer<GLPipeline>,
502 framebuffers : ResourceContainer<GLFrameBuffer>,
503
504 read_back_state : Option<ReadbackState>,
505
506 rc : AtomicIsize,
507
508 caps : DriverCaps,
509}
510
511impl Gles3Driver {
512 fn new() -> Self {
513 let mut max_rt_size = 0;
514 let mut max_tex_size = 0;
515
516 unsafe {
517 gl::GetIntegerv(gl::MAX_RENDERBUFFER_SIZE, &mut max_rt_size as *mut GLint);
518 gl::GetIntegerv(gl::MAX_TEXTURE_SIZE, &mut max_tex_size as *mut GLint);
519 }
520
521 let min_surface_size = std::cmp::min(4096, std::cmp::min(max_rt_size, max_tex_size));
522 Self {
523 device_buffers : ResourceContainer::new(),
524 textures : ResourceContainer::new(),
525 render_targets : ResourceContainer::new(),
526 shaders : ResourceContainer::new(),
527 pipelines : ResourceContainer::new(),
528 framebuffers : ResourceContainer::new(),
529 rc : AtomicIsize::new(0),
530
531 read_back_state : None,
532
533 caps : DriverCaps {
534 max_2d_surface_dimension : Dimensioni::new(min_surface_size, min_surface_size),
535 }
536 }
537 }
538
539 pub fn get_framebuffer_gl_id(&self, fb_id: usize) -> GLuint {
540 self.framebuffers[fb_id].gl_id
541 }
542
543 fn initialize(mut self) -> DriverPtr {
544 self.read_back_state = Some(ReadbackState::new(&mut self));
545 unsafe {
546 gl::Enable(gl::SCISSOR_TEST);
547 gl::BindFramebuffer(gl::FRAMEBUFFER, 0);
548 IntrusivePtr::from_raw_no_increment(IntrusivePtr::new(self).into_raw_mut() as *mut dyn Driver)
549 }
550 }
551
552 fn buffer_type_to_gl(bt: &DeviceBufferDesc) -> GLenum {
553 match bt {
554 DeviceBufferDesc::Vertex(_) => gl::ARRAY_BUFFER,
555 DeviceBufferDesc::Index(_) => gl::ELEMENT_ARRAY_BUFFER,
556 DeviceBufferDesc::Pixel(_) => gl::PIXEL_UNPACK_BUFFER,
557 }
558 }
559
560 fn buffer_usage_to_gl(bt: &DeviceBufferDesc) -> GLenum {
561 let usage =
562 match bt {
563 DeviceBufferDesc::Vertex(u) |
564 DeviceBufferDesc::Index(u) |
565 DeviceBufferDesc::Pixel(u) => u,
566 };
567
568 match usage {
569 Usage::Static(_) => gl::STATIC_DRAW,
570 Usage::Streamed(_) => gl::STREAM_DRAW,
571 Usage::Dynamic(_) => gl::DYNAMIC_DRAW,
572 }
573 }
574
575 fn buffer_data(bt: &DeviceBufferDesc) -> Option<*const u8> {
576 let usage =
577 match bt {
578 DeviceBufferDesc::Vertex(u) |
579 DeviceBufferDesc::Index(u) |
580 DeviceBufferDesc::Pixel(u) => u,
581 };
582
583 match usage {
584 Usage::Static(b) => Some(b.ptr()),
585 Usage::Streamed(_) => None,
586 Usage::Dynamic(_) => None,
587 }
588 }
589
590 fn erase_buffer_data(bt: &DeviceBufferDesc) -> DeviceBufferDesc {
591 let usage =
592 match bt {
593 DeviceBufferDesc::Vertex(u) |
594 DeviceBufferDesc::Index(u) |
595 DeviceBufferDesc::Pixel(u) => u,
596 };
597
598 let usage =
599 match usage {
600 Usage::Static(p) => Usage::Static(Box::new(NullPayload{ size: p.size() })),
601 Usage::Streamed(s) => Usage::Streamed(*s),
602 Usage::Dynamic (s) => Usage::Dynamic(*s),
603 };
604
605 match bt {
606 DeviceBufferDesc::Vertex(_) => DeviceBufferDesc::Vertex(usage),
607 DeviceBufferDesc::Index(_) => DeviceBufferDesc::Index(usage),
608 DeviceBufferDesc::Pixel(_) => DeviceBufferDesc::Pixel(usage),
609 }
610 }
611
612 fn erase_texture_data(desc: &TextureDesc) -> TextureDesc {
613 TextureDesc {
614 sampler_desc: desc.sampler_desc.clone(),
615 payload : None,
616 }
617 }
618
619 fn upload_texture(res: GLuint, desc: &SamplerDesc, data: &Option<Box<dyn Payload>>) {
620 unsafe {
621 match &desc.image_type {
622 SamplerType::Sampler2D(pch_x, pch_y) => {
623 gl::BindTexture(gl::TEXTURE_2D, res);
624 gl::PixelStorei(gl::UNPACK_ALIGNMENT, 1);
625 gl::PixelStorei(gl::PACK_ALIGNMENT, 1);
626
627 let ptr = match data {
631 Some(b) => b.ptr() as *const c_void,
632 None => ::core::ptr::null()
633 };
634
635 gl::TexImage2D(gl::TEXTURE_2D,
636 0,
637 desc.pixel_format.gl_internal_format() as GLint,
638 pch_x.size as GLsizei,
639 pch_y.size as GLsizei,
640 0,
641 desc.pixel_format.gl_format(),
642 desc.pixel_format.gl_elem_type(),
643 ptr
644 );
645
646 Self::check_gl_error();
647
648 gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_S, Self::gl_wrap(&pch_x.wrap) as GLint);
649 gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_T, Self::gl_wrap(&pch_y.wrap) as GLint);
650 match &desc.pixel_format {
651 PixelFormat::R8(min_mag) | PixelFormat::RGB8(min_mag) | PixelFormat::RGBA8(min_mag) => {
652 gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, Self::gl_filter(&min_mag.min_filter) as GLint);
653 gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, Self::gl_filter(&min_mag.mag_filter) as GLint);
654 },
655 _ => {
656 gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::NEAREST as GLint);
657 gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::NEAREST as GLint);
658 }
659 }
660 }
661 }
662 }
663 }
664 fn create_texture(desc: &SamplerDesc, data: &Option<Box<dyn Payload>>) -> GLuint {
665 unsafe {
666
667 let mut res : GLuint = 0;
668 gl::GenTextures(1, &mut res);
669 Self::upload_texture(res, desc, data);
670 res
671 }
672 }
673
674 fn create_render_target(desc: &SamplerDesc, _sample_size: usize) -> GLuint {
675 unsafe {
676 let mut res : GLuint = 0;
677 gl::GenRenderbuffers(1, &mut res);
678 match &desc.image_type {
679 SamplerType::Sampler2D(pch_x, pch_y) => {
680 gl::BindRenderbuffer(gl::RENDERBUFFER, res);
681 gl::RenderbufferStorage(gl::RENDERBUFFER,
682 desc.pixel_format.gl_internal_format(),
683 pch_x.size as GLsizei,
684 pch_y.size as GLsizei
685 );
686 if gl::GetError() != gl::NO_ERROR {
687 panic!("Error creating render target");
688 }
689 }
690 }
691 res
692 }
693 }
694
695 fn gl_wrap(wm: &WrapMode) -> GLenum {
696 match wm {
697 WrapMode::Repeat => gl::REPEAT,
698 WrapMode::ClampToEdge => gl::CLAMP_TO_EDGE,
699 WrapMode::ClampToBorder => panic!("unsupported wrap mode!"),
700 WrapMode::MirroredRepeat => gl::MIRRORED_REPEAT,
701 }
702 }
703
704 fn gl_filter(filter: &Filter) -> GLenum {
705 match filter {
706 Filter::Nearest => gl::NEAREST,
707 Filter::Linear => gl::LINEAR,
708 Filter::NearestMipmapNearest => gl::NEAREST_MIPMAP_NEAREST,
709 Filter::NearestMipmapLinear => gl::NEAREST_MIPMAP_LINEAR,
710 Filter::LinearMipmapNearest => gl::LINEAR_MIPMAP_NEAREST,
711 Filter::LinearMipmapLinear => gl::LINEAR_MIPMAP_LINEAR,
712 }
713 }
714
715 fn load_shader(src: &str, ty: GLenum) -> Option<GLuint> {
716 unsafe {
717 let shader = gl::CreateShader(ty);
718 if shader == 0 {
719 return None
720 }
721
722 let c_str = std::ffi::CString::new(src.as_bytes()).unwrap();
723 gl::ShaderSource(shader, 1, &(c_str.as_ptr() as *const i8), core::ptr::null());
724 gl::CompileShader(shader);
725
726 let mut compiled = 0;
727 gl::GetShaderiv(shader, gl::COMPILE_STATUS, &mut compiled);
728
729 let mut info_len = 0;
730 gl::GetShaderiv(shader, gl::INFO_LOG_LENGTH, &mut info_len);
731 if info_len > 1 {
732 let s = alloc_string(info_len as usize);
733 gl::GetShaderInfoLog(shader, info_len as GLsizei, core::ptr::null_mut(), s.as_ptr() as *mut GLchar);
734 let sht =
735 match ty {
736 gl::VERTEX_SHADER => "vertex shader",
737 gl::FRAGMENT_SHADER => "fragment shader",
738 _ => panic!("invalid shader type")
739 };
740
741 println!("[{}] Compilation Log: {}", sht, s);
742 free_string(s, info_len as usize);
743 }
744
745 if compiled == 0 {
746 gl::DeleteShader(shader);
747 return None
748 }
749 Some(shader)
750 }
751 }
752
753 fn delete_device_buffer(&mut self, buff: usize) {
754 self.device_buffers.remove(buff)
755 }
756
757 fn delete_texture(&mut self, surf: usize) {
758 self.textures.remove(surf)
759 }
760
761 fn delete_render_target(&mut self, surf: usize) {
762 self.render_targets.remove(surf)
763 }
764
765 fn delete_shader(&mut self, shader: usize) {
766 self.shaders.remove(shader)
767 }
768
769 fn delete_pipeline(&mut self, pipe: usize) {
770 self.pipelines.remove(pipe)
771 }
772
773 fn delete_frame_buffer(&mut self, pass: usize) {
774 self.framebuffers.remove(pass)
775 }
776
777 pub fn check_gl_error() {
778 unsafe {
779 let error = gl::GetError();
780 if error != gl::NO_ERROR {
781 panic!("Error : {:#X}", error);
782 }
783 }
784 }
785
786 fn read_back_state(&mut self) -> &ReadbackState {
787 match &self.read_back_state {
788 Some(rb) => &rb,
789 _ => panic!("readback is None")
790 }
791 }
792}
793
794
795impl Driver for Gles3Driver {
796 fn get_caps(&self) -> &DriverCaps { &self.caps }
797
798 fn create_device_buffer(&mut self, desc: DeviceBufferDesc) -> Option<DeviceBufferPtr> {
799 unsafe {
800 let data = Self::buffer_data(&desc);
801 let mut buff = 0;
802 gl::GenBuffers(1, &mut buff);
803 gl::BindBuffer(Self::buffer_type_to_gl(&desc), buff);
804 let buff_data =
805 match data {
806 Some(d) => d,
807 None => std::ptr::null(),
808 };
809
810 gl::BufferData(Self::buffer_type_to_gl(&desc), desc.size() as GLsizeiptr, buff_data as *const rs_ctypes::c_void, Self::buffer_usage_to_gl(&desc));
811
812 let gl_buff = GLDeviceBuffer { gl_id: buff, desc: Self::erase_buffer_data(&desc) };
813 let idx = self.device_buffers.add(gl_buff);
814
815 let iptr : IntrusivePtr<dyn Driver>= IntrusivePtr::from_raw_increment(self as *mut Self as *mut dyn Driver);
816
817 Some(DeviceBufferPtr::new(DeviceBuffer::new(ResourceType::DeviceBuffer, idx, desc, Some(iptr))))
818 }
819 }
820
821 fn create_texture(&mut self, desc: TextureDesc) -> Option<TexturePtr> {
822 let new_desc = Self::erase_texture_data(&desc);
823 let idx = Self::create_texture(&desc.sampler_desc, &desc.payload);
824 let img = GLTexture { gl_id: idx };
825 let idx = self.textures.add(img);
826
827 let iptr : IntrusivePtr<dyn Driver>= unsafe { IntrusivePtr::from_raw_increment(self as *mut Self as *mut dyn Driver) };
828
829 Some(TexturePtr::new(Texture::new(ResourceType::Texture, idx, new_desc, Some(iptr))))
830 }
831
832 fn create_render_target(&mut self, desc: RenderTargetDesc) -> Option<RenderTargetPtr> {
833 let idx = Self::create_render_target(&desc.sampler_desc, desc.sample_count);
834 let img = GLRenderTarget { gl_id: idx };
835 let idx = self.render_targets.add(img);
836
837 let iptr : IntrusivePtr<dyn Driver>= unsafe { IntrusivePtr::from_raw_increment(self as *mut Self as *mut dyn Driver) };
838
839 Some(RenderTargetPtr::new(RenderTarget::new(ResourceType::RenderTarget, idx, desc, Some(iptr))))
840 }
841
842 fn create_shader(&mut self, desc: ShaderDesc) -> Option<ShaderPtr> {
843 let desc_copy2 = desc.clone();
844 unsafe {
845 let program_object = gl::CreateProgram();
846 if program_object == 0 {
847 return None
848 }
849
850 let vertex_shader = Self::load_shader(desc.vertex_shader.as_str(), gl::VERTEX_SHADER);
851 let fragment_shader = Self::load_shader(desc.pixel_shader.as_str(), gl::FRAGMENT_SHADER);
852
853 match (vertex_shader, fragment_shader) {
854 (None, None) => (),
855 (None, Some(f)) => gl::DeleteShader(f),
856 (Some(v), None) => gl::DeleteShader(v),
857 (Some(v), Some(f)) => {
858 gl::AttachShader(program_object, v);
859 gl::AttachShader(program_object, f);
860 gl::LinkProgram(program_object);
861
862 let mut linked = 0;
863 gl::GetProgramiv(program_object, gl::LINK_STATUS, &mut linked);
864 let mut info_len = 0;
865 gl::GetProgramiv(program_object, gl::INFO_LOG_LENGTH, &mut info_len);
866 if info_len > 1 {
867 let s = alloc_string(info_len as usize);
868 gl::GetProgramInfoLog(program_object, info_len as GLsizei, core::ptr::null_mut(), s.as_ptr() as *mut GLchar);
869 println!("Shader Linking: {}", s);
870 free_string(s, info_len as usize);
871 }
872
873
874 gl::DetachShader(program_object, v);
876 gl::DetachShader(program_object, f);
877
878 gl::DeleteShader(f);
879 gl::DeleteShader(v);
880
881 if linked == 0 {
882 gl::DeleteProgram(program_object);
883 return None
884 }
885 }
886 }
887
888 let mut vertex_attributes = Vec::new();
889
890 for l in desc.vertex_attributes {
891 let mut vas = Vec::new();
892 for a in l {
893 let mut s = a.clone();
894 s.push('\0');
895
896 let au = gl::GetAttribLocation(program_object, s.as_bytes().as_ptr() as *const GLchar);
897 if au < 0 {
898 println!("attribute {} not found in shader", s);
899 return None }
901 vas.push((s, au as GLuint));
902 }
903 vertex_attributes.push(vas);
904 }
905
906 let mut vertex_uniforms = Vec::new();
907
908 for u in desc.vertex_uniforms {
909 let mut s = u.clone();
910 s.push('\0');
911
912 let au = gl::GetUniformLocation(program_object, s.as_bytes().as_ptr() as *const GLchar);
913 if au < 0 {
914 println!("uniform {} not found in shader", s);
915 return None }
917 vertex_uniforms.push((s, au as GLuint));
918 }
919
920 let mut vertex_surfaces = Vec::new();
921
922 for u in desc.vertex_surfaces {
923 let mut s = u.clone();
924 s.push('\0');
925
926 let au = gl::GetUniformLocation(program_object, s.as_bytes().as_ptr() as *const GLchar);
927 if au < 0 {
928 println!("vertex texture {} not found in shader", s);
929 return None }
931 vertex_surfaces.push((s, au as GLuint));
933 }
934
935 let mut pixel_uniforms = Vec::new();
936
937 for u in desc.pixel_uniforms {
938 let mut s = u.clone();
939 s.push('\0');
940
941 let au = gl::GetUniformLocation(program_object, s.as_bytes().as_ptr() as *const GLchar);
942 if au < 0 {
943 println!("uniform {} not found in shader", s);
944 return None }
946 pixel_uniforms.push((s, au as GLuint));
947 }
948
949 let mut pixel_surfaces = Vec::new();
950
951 for u in desc.pixel_surfaces {
952 let mut s = u.clone();
953 s.push('\0');
954
955 let au = gl::GetUniformLocation(program_object, s.as_bytes().as_ptr() as *const GLchar);
956 if au < 0 {
957 println!("pixel texture {} not found in shader", s);
958 return None }
960 pixel_surfaces.push((s, au as GLuint));
962 }
963
964 let gl_shader =
965 GLShader {
966 gl_id : program_object,
967
968 vertex_attributes : vertex_attributes,
969
970 vertex_uniforms : vertex_uniforms,
971 vertex_surfaces : vertex_surfaces,
972
973 pixel_uniforms : pixel_uniforms,
974 pixel_surfaces : pixel_surfaces,
975 };
976
977 let idx = self.shaders.add(gl_shader);
978
979 let iptr : IntrusivePtr<dyn Driver>= IntrusivePtr::from_raw_increment(self as *mut Self as *mut dyn Driver);
980
981 Some(ShaderPtr::new(Shader::new(ResourceType::Shader, idx, desc_copy2, Some(iptr))))
982 }
983 }
984
985 fn create_pipeline(&mut self, desc: PipelineDesc) -> Option<PipelinePtr> {
986 let idx = self.pipelines.add(GLPipeline { desc: desc.clone() });
987
988 let iptr : IntrusivePtr<dyn Driver>= unsafe { IntrusivePtr::from_raw_increment(self as *mut Self as *mut dyn Driver) };
989
990 Some(PipelinePtr::new(Pipeline::new(ResourceType::Pipeline, idx, desc, Some(iptr))))
991 }
992
993 fn create_frame_buffer(&mut self, desc: FrameBufferDesc) -> Option<FrameBufferPtr> {
994 unsafe {
995 let mut res : GLuint = 0;
996 gl::GenFramebuffers(1, &mut res);
997 gl::BindFramebuffer(gl::FRAMEBUFFER, res);
998
999 let mut colors : [u32; 4] = [0; 4];
1000 for i in 0..4u32 {
1001 match &desc.color_attachements[i as usize] {
1002 Some(SurfaceAttachment::Texture(ca)) => {
1003 let gl_id = self.textures[ca.res_id()].gl_id;
1004 colors[i as usize] = gl_id;
1005 gl::FramebufferTexture2D(gl::FRAMEBUFFER, gl::COLOR_ATTACHMENT0 + i, gl::TEXTURE_2D, gl_id, 0);
1006 },
1007 Some(SurfaceAttachment::RenderTarget(ca)) => {
1008 let gl_id = self.render_targets[ca.res_id()].gl_id;
1009 colors[i as usize] = gl_id;
1010 gl::FramebufferRenderbuffer(gl::FRAMEBUFFER, gl::COLOR_ATTACHMENT0 + i, gl::RENDERBUFFER, gl_id);
1011 },
1012 _ => ()
1013 }
1014 }
1015
1016 match &desc.depth_stencil_attachement {
1017 SurfaceAttachment::RenderTarget(ca) => {
1018 let gl_id = self.render_targets[ca.res_id()].gl_id;
1019 gl::FramebufferRenderbuffer(gl::FRAMEBUFFER, gl::DEPTH_ATTACHMENT, gl::RENDERBUFFER, gl_id);
1020 },
1021 SurfaceAttachment::Texture(ca) => {
1022 let gl_id = self.textures[ca.res_id()].gl_id;
1023 gl::FramebufferTexture2D(gl::FRAMEBUFFER, gl::DEPTH_ATTACHMENT, gl::TEXTURE_2D, gl_id, 0);
1024 }
1025 }
1026
1027 if gl::CheckFramebufferStatus(gl::FRAMEBUFFER) != gl::FRAMEBUFFER_COMPLETE {
1028 println!("Framebuffer is not complete!");
1029 gl::DeleteFramebuffers(1, &mut res);
1030 return None
1031 }
1032
1033 let mut color0 = 0;
1034 gl::GetFramebufferAttachmentParameteriv(gl::FRAMEBUFFER, gl::COLOR_ATTACHMENT0 as GLenum, gl::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME as GLenum, &mut color0);
1035 assert_ne!(colors[0], 0);
1036 assert_eq!(colors[0], color0 as u32);
1037
1038 Self::check_gl_error();
1039
1040 let idx = self.framebuffers.add(GLFrameBuffer { desc: desc.clone(), gl_id: res });
1041
1042 let iptr : IntrusivePtr<dyn Driver>= IntrusivePtr::from_raw_increment(self as *mut Self as *mut dyn Driver);
1043
1044 gl::BindFramebuffer(gl::FRAMEBUFFER, 0);
1045
1046 Some(FrameBufferPtr::new(FrameBuffer::new(ResourceType::FrameBuffer, idx, desc, Some(iptr))))
1047 }
1048 }
1049
1050 fn delete_resource(&mut self, resource_type: &ResourceType, res_id: usize) {
1051 match resource_type {
1052 ResourceType::DeviceBuffer => self.delete_device_buffer(res_id),
1053 ResourceType::Texture => self.delete_texture(res_id),
1054 ResourceType::RenderTarget => self.delete_render_target(res_id),
1055 ResourceType::Shader => self.delete_shader(res_id),
1056 ResourceType::Pipeline => self.delete_pipeline(res_id),
1057 ResourceType::FrameBuffer => self.delete_frame_buffer(res_id),
1058 }
1059 }
1060
1061 fn draw(&mut self, pipe: &Pipeline, bindings: &Bindings, uniforms: *const c_void, prim_count: u32, instance_count: u32) {
1062 unsafe {
1063 let gl_pipe = &self.pipelines[pipe.res_id()];
1064 let gl_prog = &self.shaders[gl_pipe.desc.shader.res_id()];
1065
1066 match &gl_pipe.desc.blend {
1068 BlendOp::Add(blend) | BlendOp::Subtract(blend) => {
1069 gl::Enable(gl::BLEND);
1070 gl::BlendFuncSeparate(
1071 blend.src_factor_rgb.gl_blend_factor(),
1072 blend.dst_factor_rgb.gl_blend_factor(),
1073 blend.src_factor_alpha.gl_blend_factor(),
1074 blend.dst_factor_alpha.gl_blend_factor());
1075 },
1076 _ => gl::Disable(gl::BLEND),
1077 }
1078
1079 match &gl_pipe.desc.blend {
1080 BlendOp::Add(_) => gl::BlendEquationSeparate(gl::FUNC_ADD, gl::FUNC_ADD),
1081 BlendOp::Subtract(_) => gl::BlendEquationSeparate(gl::FUNC_SUBTRACT, gl::FUNC_SUBTRACT),
1082 BlendOp::ReverseSubtract(_) => gl::BlendEquationSeparate(gl::FUNC_REVERSE_SUBTRACT, gl::FUNC_REVERSE_SUBTRACT),
1083 _ => ()
1084 }
1085
1086 let (gl_prim, gl_elem_count) =
1087 match gl_pipe.desc.primitive_type {
1088 PrimitiveType::Lines => (gl::LINES, 2 * prim_count),
1089 PrimitiveType::LineStrip => (gl::LINE_STRIP, 1 + prim_count),
1090 PrimitiveType::Points => (gl::POINTS, prim_count),
1091 PrimitiveType::Triangles => (gl::TRIANGLES, 3 * prim_count),
1092 PrimitiveType::TriangleStrip => (gl::TRIANGLE_STRIP, 2 + prim_count)
1093 };
1094
1095 match gl_pipe.desc.cull_mode {
1096 CullMode::None => gl::Disable(gl::CULL_FACE),
1097 CullMode::Winding => gl::Enable(gl::CULL_FACE),
1098 }
1099
1100 match gl_pipe.desc.face_winding {
1101 FaceWinding::CCW => gl::CullFace(gl::BACK),
1102 FaceWinding::CW => gl::CullFace(gl::FRONT),
1103 }
1104
1105 if gl_pipe.desc.depth_test {
1106 gl::Enable(gl::DEPTH_TEST)
1107 } else {
1108 gl::Disable(gl::DEPTH_TEST)
1109 }
1110
1111 gl::DepthMask(if gl_pipe.desc.depth_write { gl::TRUE } else { gl::FALSE } as GLboolean);
1112
1113 gl::UseProgram(gl_prog.gl_id);
1114 for (l, layout) in gl_pipe.desc.buffer_layouts.iter().enumerate() {
1115 let gl_vb = &self.device_buffers[bindings.vertex_buffers[layout.buffer_id].res_id()];
1116 gl::BindBuffer(gl::ARRAY_BUFFER, gl_vb.gl_id);
1117 for (i, a) in layout.vertex_attributes.iter().enumerate() {
1118 let aidx = &gl_prog.vertex_attributes[l][i];
1119 gl::EnableVertexAttribArray(aidx.1);
1120 match a.format() {
1121 VertexFormat::Int |
1122 VertexFormat::Int2 |
1123 VertexFormat::Int3 |
1124 VertexFormat::Int4 |
1125 VertexFormat::UInt |
1126 VertexFormat::UInt2 |
1127 VertexFormat::UInt3 |
1128 VertexFormat::UInt4 => {
1129 gl::VertexAttribIPointer(aidx.1, a.format().gl_elem_count() as GLint, a.format().gl_elem_type(), layout.stride as GLint, a.offset() as *const c_void);
1130 },
1131 _ => {
1132 gl::VertexAttribPointer(aidx.1, a.format().gl_elem_count() as GLint, a.format().gl_elem_type(), a.format().gl_is_normalized(), layout.stride as GLint, a.offset() as *const c_void);
1133 }
1134 }
1135 gl::VertexAttribDivisor(aidx.1, layout.divisor as GLuint);
1136 }
1137 }
1138
1139 setup_uniforms(uniforms, gl_pipe.desc.uniform_descs.as_slice(), gl_prog.vertex_uniforms.as_slice());
1140
1141 for (i, t) in bindings.vertex_images.iter().enumerate() {
1142 let location = gl_prog.vertex_surfaces[i].1;
1143 gl::ActiveTexture(((gl::TEXTURE0 as usize) + i) as GLenum);
1144 gl::BindTexture(gl::TEXTURE_2D, self.textures[t.res_id()].gl_id as GLuint);
1145 gl::Uniform1i(location as GLint, i as GLint);
1146 }
1147
1148 let pixel_sampler_offset = bindings.vertex_images.len();
1149
1150 for (i, t) in bindings.pixel_images.iter().enumerate() {
1151 let location = gl_prog.pixel_surfaces[i].1;
1152 gl::ActiveTexture(((gl::TEXTURE0 as usize) + i + pixel_sampler_offset) as GLenum);
1153 gl::BindTexture(gl::TEXTURE_2D, self.textures[t.res_id()].gl_id as GLuint);
1154 gl::Uniform1i(location as GLint, (i + pixel_sampler_offset) as GLint);
1155 }
1156
1157 match &bindings.index_buffer {
1158 Some(ib) => {
1159 gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, self.device_buffers[ib.res_id()].gl_id);
1160
1161 let itype =
1162 match gl_pipe.desc.index_type {
1163 IndexType::None => panic!("attempt to bind an index buffer to a pipeline that doesn't support it"),
1164 IndexType::UInt16 => gl::UNSIGNED_SHORT,
1165 IndexType::UInt32 => gl::UNSIGNED_INT,
1166 };
1167
1168 gl::DrawElementsInstanced(gl_prim, gl_elem_count as GLsizei, itype, core::ptr::null() as *const rs_ctypes::c_void, instance_count as GLint);
1169 },
1170 None => {
1171 if gl_pipe.desc.index_type != IndexType::None {
1172 panic!("no index buffer bound but index type exist in pipeline")
1173 }
1174 gl::DrawArraysInstanced(gl_prim, 0, gl_elem_count as GLsizei, instance_count as GLint);
1175 }
1176 }
1177
1178 for l in &gl_prog.vertex_attributes {
1179 for v in l {
1180 gl::DisableVertexAttribArray(v.1);
1181 }
1182 }
1183 }
1184 }
1185
1186 fn begin_pass(&mut self, pass: &Pass) {
1187 unsafe {
1188 gl::Flush();
1189 gl::Viewport(0, 0, pass.width as i32, pass.height as i32);
1190 gl::Scissor(0, 0, pass.width as i32, pass.height as i32);
1191
1192 match &pass.frame_buffer {
1193 None => {
1194 gl::BindFramebuffer(gl::FRAMEBUFFER, 0);
1195 Self::check_gl_error();
1196 },
1197
1198 Some(fb) => {
1199 gl::BindFramebuffer(gl::FRAMEBUFFER, self.framebuffers[fb.res_id()].gl_id);
1200 Self::check_gl_error();
1201 },
1202 }
1203
1204 match &pass.frame_buffer {
1206 Some(fb) => {
1207 let fb_ref = &self.framebuffers[fb.res_id()];
1208 let mut draw_buffer : [GLenum; 4] = [ gl::NONE, gl::NONE, gl::NONE, gl::NONE ];
1209 for (idx, attach) in fb_ref.desc.color_attachements.iter().enumerate() {
1210 match attach {
1211 Some(_) => {
1212 draw_buffer[idx] = gl::COLOR_ATTACHMENT0 + (idx as GLenum);
1213 },
1214 None => (),
1215 };
1216 }
1217
1218 gl::DrawBuffers(4, &draw_buffer as *const GLenum);
1219 Self::check_gl_error();
1220
1221 for idx in 0..4 {
1222 match pass.color_actions[idx] {
1223 ColorPassAction::Clear(col) => {
1224 let surf = &fb_ref.desc.color_attachements[idx];
1225 match surf.as_ref() {
1226 Some(surf_ref) => {
1227 match surf_ref.pixel_format().to_orig_surface_type() {
1228 OrigSurfaceType::UInt => {
1229 let i_cols : [GLuint; 4] = [col.x as GLuint, col.y as GLuint, col.z as GLuint, col.w as GLuint];
1230 gl::ClearBufferuiv(gl::COLOR as GLenum, idx as GLint, i_cols.as_ptr() as *const GLuint);
1231 },
1232 OrigSurfaceType::Float => {
1233 let float_col = color4b_to_color4f(col);
1234 let f_cols : [GLfloat; 4] = [float_col.x, float_col.y, float_col.z, float_col.w];
1235 gl::ClearBufferfv(gl::COLOR as GLenum, idx as GLint, f_cols.as_ptr() as *const GLfloat);
1236 }
1237 }
1238 },
1239 _ => { let float_col = color4b_to_color4f(col);
1241 let f_cols : [GLfloat; 4] = [float_col.x, float_col.y, float_col.z, float_col.w];
1242 gl::ClearBufferfv(gl::COLOR as GLenum, idx as GLint, f_cols.as_ptr() as *const GLfloat);
1243 }
1244 }
1245 Self::check_gl_error();
1246 },
1247 _ => ()
1248 }
1249 }
1250
1251 match pass.depth_action {
1253 DepthPassAction::Clear(f) => {
1254 gl::ClearBufferfv(gl::DEPTH as GLenum, 0, &f as *const _ as *const GLfloat);
1255 Self::check_gl_error();
1256
1257 },
1258 _ => ()
1259 }
1260 },
1261 None => {
1262 let mut bits = 0;
1264 for idx in 0..4 {
1265 match pass.color_actions[idx] {
1266 ColorPassAction::Clear(col) => {
1267 let float_col = color4b_to_color4f(col);
1268 let f_cols : [GLfloat; 4] = [float_col.x, float_col.y, float_col.z, float_col.w];
1269 gl::ClearColor(f_cols[0], f_cols[1], f_cols[2], f_cols[3]);
1270
1271 bits |= gl::COLOR_BUFFER_BIT;
1272 },
1273 _ => ()
1274 }
1275 }
1276
1277 match pass.depth_action {
1278 DepthPassAction::Clear(depth) => {
1279 gl::ClearDepthf(depth);
1280 bits |= gl::DEPTH_BUFFER_BIT;
1281 },
1282 _ => ()
1283 }
1284 gl::Clear(bits);
1285 Self::check_gl_error();
1286 }
1287 }
1288
1289 }
1290 }
1291
1292 fn end_pass(&mut self) {
1293 }
1294
1295 fn set_viewport(&mut self, x: u32, y: u32, w: u32, h: u32) {
1296 unsafe { gl::Viewport(x as GLint, y as GLint, w as GLsizei, h as GLsizei) }
1297 }
1298
1299 fn set_scissor(&mut self, x: u32, y: u32, w: u32, h: u32) {
1300 unsafe {
1301 gl::Scissor(x as GLint, y as GLint, w as GLsizei, h as GLsizei)
1302 }
1303 }
1304
1305 fn update_device_buffer(&mut self, dev_buf: &mut DeviceBufferPtr, offset: usize, pl: &dyn Payload) {
1306 unsafe {
1307 match self.device_buffers[dev_buf.res_id()].desc {
1308 DeviceBufferDesc::Vertex(Usage::Static(_)) |
1309 DeviceBufferDesc::Index(Usage::Static(_)) |
1310 DeviceBufferDesc::Pixel(Usage::Static(_)) => {
1311 panic!("trying to update static buffer")
1313 },
1314 _ => (), };
1316
1317 let buff_size = self.device_buffers[dev_buf.res_id()].desc.size();
1318 if pl.size() + offset > buff_size {
1319 panic!("payload exceeds device buffer size")
1320 }
1321
1322 let target =
1323 match self.device_buffers[dev_buf.res_id()].desc {
1324 DeviceBufferDesc::Vertex(_) => gl::ARRAY_BUFFER,
1325 DeviceBufferDesc::Index(_) => gl::ELEMENT_ARRAY_BUFFER,
1326 DeviceBufferDesc::Pixel(_) => gl::PIXEL_UNPACK_BUFFER,
1327 };
1328 gl::BindBuffer(target, self.device_buffers[dev_buf.res_id()].gl_id as GLuint);
1329 let ptr = gl::MapBufferRange(target, offset as GLintptr, pl.size() as GLsizeiptr, gl::MAP_WRITE_BIT as GLbitfield) as *mut u8;
1330 Self::check_gl_error();
1331
1332 std::ptr::copy_nonoverlapping(pl.ptr() as *mut u8, ptr, pl.size());
1333
1334 assert_eq!(gl::UnmapBuffer(target), gl::TRUE as GLboolean);
1335 Self::check_gl_error();
1336 }
1337 }
1338
1339 fn update_texture(&mut self, dev_buf: &mut TexturePtr, pl: Box<dyn Payload>) {
1340 let res_id = dev_buf.res_id();
1342 let gl_id = self.textures[res_id].gl_id;
1343 Self::upload_texture(gl_id, &dev_buf.desc().sampler_desc, &Some(pl));
1344 }
1345
1346 fn read_back(&mut self, surface: &TexturePtr, x: u32, y: u32, w: u32, h: u32) -> Option<ReadbackPayload> {
1347 unsafe {
1348 let rb = self.read_back_state() as *const ReadbackState as *mut ReadbackState;
1349 (&mut (*rb)).read_surface(self, surface, x, y, w, h)
1350 }
1351 }
1352}
1353
1354impl IntrusiveCounter for Gles3Driver {
1355 fn increment(&mut self) { self.rc.fetch_add(1, Ordering::SeqCst); }
1356 fn decrement(&mut self) -> isize {
1357 self.rc.fetch_sub(1, Ordering::SeqCst)
1358 }
1359}
1360
1361impl Drop for Gles3Driver {
1362 fn drop(&mut self) {
1363 println!("Gles3Driver dropped - All is good!")
1364 }
1365}
1366
1367pub fn get_driver() -> DriverPtr {
1368 unsafe {
1369 let mut range : [GLint; 2] = [0, 0];
1370 let mut precision = 0;
1371
1372 gl::GetShaderPrecisionFormat(gl::FRAGMENT_SHADER, gl::HIGH_FLOAT, range.as_mut_ptr(), &mut precision);
1373 println!("highp float range: {:?} - precision: {}", range, precision);
1374
1375 gl::GetShaderPrecisionFormat(gl::FRAGMENT_SHADER, gl::HIGH_INT, range.as_mut_ptr(), &mut precision);
1376 println!("highp int range: {:?} - precision: {}", range, precision);
1377
1378 gl::GetShaderPrecisionFormat(gl::FRAGMENT_SHADER, gl::MEDIUM_FLOAT, range.as_mut_ptr(), &mut precision);
1379 println!("mediump float range: {:?} - precision: {}", range, precision);
1380
1381 gl::GetShaderPrecisionFormat(gl::FRAGMENT_SHADER, gl::MEDIUM_INT, range.as_mut_ptr(), &mut precision);
1382 println!("mediump int range: {:?} - precision: {}", range, precision);
1383
1384 gl::GetShaderPrecisionFormat(gl::FRAGMENT_SHADER, gl::LOW_FLOAT, range.as_mut_ptr(), &mut precision);
1385 println!("lowp float range: {:?} - precision: {}", range, precision);
1386
1387 gl::GetShaderPrecisionFormat(gl::FRAGMENT_SHADER, gl::LOW_INT, range.as_mut_ptr(), &mut precision);
1388 println!("lowp int range: {:?} - precision: {}", range, precision);
1389
1390 }
1391 Gles3Driver::new().initialize()
1392}