diff --git a/renderer/src/gpu/d3d9/mod.rs b/renderer/src/gpu/d3d9/mod.rs new file mode 100644 index 00000000..6f67f3bc --- /dev/null +++ b/renderer/src/gpu/d3d9/mod.rs @@ -0,0 +1,12 @@ +// pathfinder/renderer/src/gpu/d3d9/mod.rs +// +// Copyright © 2020 The Pathfinder Project Developers. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub mod renderer; +pub mod shaders; diff --git a/renderer/src/gpu/d3d9/renderer.rs b/renderer/src/gpu/d3d9/renderer.rs new file mode 100644 index 00000000..9f1e2e16 --- /dev/null +++ b/renderer/src/gpu/d3d9/renderer.rs @@ -0,0 +1,573 @@ +// pathfinder/renderer/src/gpu/d3d9/renderer.rs +// +// Copyright © 2020 The Pathfinder Project Developers. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use crate::gpu::blend::{BlendModeExt, ToBlendState}; +use crate::gpu::perf::TimerFuture; +use crate::gpu::renderer::{FramebufferFlags, MASK_FRAMEBUFFER_HEIGHT, MASK_FRAMEBUFFER_WIDTH}; +use crate::gpu::renderer::{RendererCore, RendererFlags}; +use crate::gpu::d3d9::shaders::{ClipTileCombineVertexArrayD3D9, ClipTileCopyVertexArrayD3D9}; +use crate::gpu::d3d9::shaders::{CopyTileVertexArray, FillVertexArrayD3D9}; +use crate::gpu::d3d9::shaders::{ProgramsD3D9, TileVertexArrayD3D9}; +use crate::gpu_data::{Clip, DrawTileBatchD3D9, Fill, TileBatchTexture, TileObjectPrimitive}; +use crate::tile_map::DenseTileMap; +use crate::tiles::{TILE_HEIGHT, TILE_WIDTH}; +use byte_slice_cast::AsByteSlice; +use pathfinder_color::ColorF; +use pathfinder_content::effects::BlendMode; +use pathfinder_geometry::rect::RectI; +use pathfinder_geometry::transform3d::Transform4F; +use pathfinder_geometry::vector::{Vector2I, Vector4F, vec2i}; +use pathfinder_gpu::allocator::{BufferID, BufferTag, FramebufferID, FramebufferTag}; +use pathfinder_gpu::allocator::{TextureID, TextureTag}; +use pathfinder_gpu::{BlendFactor, BlendState, BufferTarget, ClearOps, Device, Primitive}; +use pathfinder_gpu::{RenderOptions, RenderState, RenderTarget, StencilFunc, StencilState}; +use pathfinder_gpu::{TextureDataRef, TextureFormat, UniformData}; +use pathfinder_resources::ResourceLoader; +use pathfinder_simd::default::F32x2; +use std::u32; + +const MAX_FILLS_PER_BATCH: usize = 0x10000; + +pub(crate) struct RendererD3D9 where D: Device { + // Basic data + programs: ProgramsD3D9, + quads_vertex_indices_buffer_id: Option, + quads_vertex_indices_length: usize, + + // Fills. + buffered_fills: Vec, + pending_fills: Vec, + + // Temporary framebuffers + dest_blend_framebuffer_id: FramebufferID, +} + +impl RendererD3D9 where D: Device { + pub(crate) fn new(core: &mut RendererCore, resources: &dyn ResourceLoader) + -> RendererD3D9 { + let programs = ProgramsD3D9::new(&core.device, resources); + + let window_size = core.options.dest.window_size(&core.device); + let dest_blend_framebuffer_id = + core.allocator.allocate_framebuffer(&core.device, + window_size, + TextureFormat::RGBA8, + FramebufferTag("DestBlendD3D9")); + + RendererD3D9 { + programs, + quads_vertex_indices_buffer_id: None, + quads_vertex_indices_length: 0, + + buffered_fills: vec![], + pending_fills: vec![], + + dest_blend_framebuffer_id, + } + } + + pub(crate) fn upload_and_draw_tiles(&mut self, + core: &mut RendererCore, + batch: &DrawTileBatchD3D9) { + if !batch.clips.is_empty() { + let clip_buffer_info = self.upload_clip_tiles(core, &batch.clips); + self.clip_tiles(core, &clip_buffer_info); + core.allocator.free_buffer(clip_buffer_info.clip_buffer_id); + } + + let tile_buffer = self.upload_tiles(core, &batch.tiles); + let z_buffer_texture_id = self.upload_z_buffer(core, &batch.z_buffer_data); + + self.draw_tiles(core, + batch.tiles.len() as u32, + tile_buffer.tile_vertex_buffer_id, + batch.color_texture, + batch.blend_mode, + z_buffer_texture_id); + + core.allocator.free_texture(z_buffer_texture_id); + core.allocator.free_buffer(tile_buffer.tile_vertex_buffer_id); + } + + fn upload_tiles(&mut self, core: &mut RendererCore, tiles: &[TileObjectPrimitive]) + -> TileBufferD3D9 { + let tile_vertex_buffer_id = + core.allocator.allocate_buffer::(&core.device, + tiles.len() as u64, + BufferTag("TileD3D9")); + let tile_vertex_buffer = &core.allocator.get_buffer(tile_vertex_buffer_id); + core.device.upload_to_buffer(tile_vertex_buffer, 0, tiles, BufferTarget::Vertex); + self.ensure_index_buffer(core, tiles.len()); + + TileBufferD3D9 { tile_vertex_buffer_id } + } + + + fn ensure_index_buffer(&mut self, core: &mut RendererCore, mut length: usize) { + length = length.next_power_of_two(); + if self.quads_vertex_indices_length >= length { + return; + } + + // TODO(pcwalton): Generate these with SIMD. + let mut indices: Vec = Vec::with_capacity(length * 6); + for index in 0..(length as u32) { + indices.extend_from_slice(&[ + index * 4 + 0, index * 4 + 1, index * 4 + 2, + index * 4 + 1, index * 4 + 3, index * 4 + 2, + ]); + } + + if let Some(quads_vertex_indices_buffer_id) = self.quads_vertex_indices_buffer_id.take() { + core.allocator.free_buffer(quads_vertex_indices_buffer_id); + } + let quads_vertex_indices_buffer_id = + core.allocator.allocate_buffer::(&core.device, + indices.len() as u64, + BufferTag("QuadsVertexIndicesD3D9")); + let quads_vertex_indices_buffer = + core.allocator.get_buffer(quads_vertex_indices_buffer_id); + core.device.upload_to_buffer(quads_vertex_indices_buffer, + 0, + &indices, + BufferTarget::Index); + self.quads_vertex_indices_buffer_id = Some(quads_vertex_indices_buffer_id); + self.quads_vertex_indices_length = length; + } + + pub(crate) fn add_fills(&mut self, core: &mut RendererCore, fill_batch: &[Fill]) { + if fill_batch.is_empty() { + return; + } + + core.stats.fill_count += fill_batch.len(); + + let preserve_alpha_mask_contents = core.alpha_tile_count > 0; + + self.pending_fills.reserve(fill_batch.len()); + for fill in fill_batch { + core.alpha_tile_count = core.alpha_tile_count.max(fill.link + 1); + self.pending_fills.push(*fill); + } + + core.stats.alpha_tile_count = core.alpha_tile_count as usize; + + core.reallocate_alpha_tile_pages_if_necessary(preserve_alpha_mask_contents); + + if self.buffered_fills.len() + self.pending_fills.len() > MAX_FILLS_PER_BATCH { + self.draw_buffered_fills(core); + } + + self.buffered_fills.extend(self.pending_fills.drain(..)); + } + + pub(crate) fn draw_buffered_fills(&mut self, core: &mut RendererCore) { + if self.buffered_fills.is_empty() { + return; + } + + let fill_storage_info = self.upload_buffered_fills(core); + self.draw_fills(core, fill_storage_info.fill_buffer_id, fill_storage_info.fill_count); + core.allocator.free_buffer(fill_storage_info.fill_buffer_id); + } + + fn upload_buffered_fills(&mut self, core: &mut RendererCore) -> FillBufferInfoD3D9 { + let buffered_fills = &mut self.buffered_fills; + debug_assert!(!buffered_fills.is_empty()); + + let fill_buffer_id = core.allocator.allocate_buffer::(&core.device, + MAX_FILLS_PER_BATCH as u64, + BufferTag("Fill")); + let fill_vertex_buffer = core.allocator.get_buffer(fill_buffer_id); + debug_assert!(buffered_fills.len() <= u32::MAX as usize); + core.device.upload_to_buffer(fill_vertex_buffer, 0, &buffered_fills, BufferTarget::Vertex); + + let fill_count = buffered_fills.len() as u32; + buffered_fills.clear(); + + FillBufferInfoD3D9 { fill_buffer_id, fill_count } + } + + fn draw_fills(&mut self, + core: &mut RendererCore, + fill_buffer_id: BufferID, + fill_count: u32) { + let fill_raster_program = &self.programs.fill_program; + + let fill_vertex_buffer = core.allocator.get_buffer(fill_buffer_id); + let quad_vertex_positions_buffer = core.allocator + .get_buffer(core.quad_vertex_positions_buffer_id); + let quad_vertex_indices_buffer = core.allocator + .get_buffer(core.quad_vertex_indices_buffer_id); + + let area_lut_texture = core.allocator.get_texture(core.area_lut_texture_id); + + let mask_viewport = self.mask_viewport(core); + let mask_storage = core.mask_storage.as_ref().expect("Where's the mask storage?"); + let mask_framebuffer_id = mask_storage.framebuffer_id; + let mask_framebuffer = core.allocator.get_framebuffer(mask_framebuffer_id); + + let fill_vertex_array = FillVertexArrayD3D9::new(&core.device, + fill_raster_program, + fill_vertex_buffer, + quad_vertex_positions_buffer, + quad_vertex_indices_buffer); + + let mut clear_color = None; + if !core.framebuffer_flags.contains(FramebufferFlags::MASK_FRAMEBUFFER_IS_DIRTY) { + clear_color = Some(ColorF::default()); + }; + + let timer_query = core.timer_query_cache.alloc(&core.device); + core.device.begin_timer_query(&timer_query); + + core.device.draw_elements_instanced(6, fill_count, &RenderState { + target: &RenderTarget::Framebuffer(mask_framebuffer), + program: &fill_raster_program.program, + vertex_array: &fill_vertex_array.vertex_array, + primitive: Primitive::Triangles, + textures: &[(&fill_raster_program.area_lut_texture, area_lut_texture)], + uniforms: &[ + (&fill_raster_program.framebuffer_size_uniform, + UniformData::Vec2(mask_viewport.size().to_f32().0)), + (&fill_raster_program.tile_size_uniform, + UniformData::Vec2(F32x2::new(TILE_WIDTH as f32, TILE_HEIGHT as f32))), + ], + images: &[], + storage_buffers: &[], + viewport: mask_viewport, + options: RenderOptions { + blend: Some(BlendState { + src_rgb_factor: BlendFactor::One, + src_alpha_factor: BlendFactor::One, + dest_rgb_factor: BlendFactor::One, + dest_alpha_factor: BlendFactor::One, + ..BlendState::default() + }), + clear_ops: ClearOps { color: clear_color, ..ClearOps::default() }, + ..RenderOptions::default() + }, + }); + + core.device.end_timer_query(&timer_query); + core.current_timer.as_mut().unwrap().fill_times.push(TimerFuture::new(timer_query)); + core.stats.drawcall_count += 1; + + core.framebuffer_flags.insert(FramebufferFlags::MASK_FRAMEBUFFER_IS_DIRTY); + } + + fn clip_tiles(&mut self, core: &mut RendererCore, clip_buffer_info: &ClipBufferInfo) { + // Allocate temp mask framebuffer. + let mask_temp_framebuffer_id = + core.allocator.allocate_framebuffer(&core.device, + self.mask_viewport(core).size(), + core.mask_texture_format(), + FramebufferTag("TempClipMaskD3D9")); + let mask_temp_framebuffer = core.allocator.get_framebuffer(mask_temp_framebuffer_id); + + let mask_storage = core.mask_storage.as_ref().expect("Where's the mask storage?"); + let mask_framebuffer_id = mask_storage.framebuffer_id; + let mask_framebuffer = core.allocator.get_framebuffer(mask_framebuffer_id); + let mask_texture = core.device.framebuffer_texture(mask_framebuffer); + let mask_texture_size = core.device.texture_size(&mask_texture); + + let clip_vertex_buffer = core.allocator.get_buffer(clip_buffer_info.clip_buffer_id); + let quad_vertex_positions_buffer = core.allocator + .get_buffer(core.quad_vertex_positions_buffer_id); + let quad_vertex_indices_buffer = core.allocator + .get_buffer(core.quad_vertex_indices_buffer_id); + + let tile_clip_copy_vertex_array = + ClipTileCopyVertexArrayD3D9::new(&core.device, + &self.programs.tile_clip_copy_program, + clip_vertex_buffer, + quad_vertex_positions_buffer, + quad_vertex_indices_buffer); + let tile_clip_combine_vertex_array = + ClipTileCombineVertexArrayD3D9::new(&core.device, + &self.programs.tile_clip_combine_program, + clip_vertex_buffer, + quad_vertex_positions_buffer, + quad_vertex_indices_buffer); + + let timer_query = core.timer_query_cache.alloc(&core.device); + core.device.begin_timer_query(&timer_query); + + // Copy out tiles. + // + // TODO(pcwalton): Don't do this on GL4. + core.device.draw_elements_instanced(6, clip_buffer_info.clip_count * 2, &RenderState { + target: &RenderTarget::Framebuffer(mask_temp_framebuffer), + program: &self.programs.tile_clip_copy_program.program, + vertex_array: &tile_clip_copy_vertex_array.vertex_array, + primitive: Primitive::Triangles, + textures: &[ + (&self.programs.tile_clip_copy_program.src_texture, + core.device.framebuffer_texture(mask_framebuffer)), + ], + images: &[], + uniforms: &[ + (&self.programs.tile_clip_copy_program.framebuffer_size_uniform, + UniformData::Vec2(mask_texture_size.to_f32().0)), + ], + storage_buffers: &[], + viewport: RectI::new(Vector2I::zero(), mask_texture_size), + options: RenderOptions::default(), + }); + + // Combine clip tiles. + core.device.draw_elements_instanced(6, clip_buffer_info.clip_count, &RenderState { + target: &RenderTarget::Framebuffer(mask_framebuffer), + program: &self.programs.tile_clip_combine_program.program, + vertex_array: &tile_clip_combine_vertex_array.vertex_array, + primitive: Primitive::Triangles, + textures: &[ + (&self.programs.tile_clip_combine_program.src_texture, + core.device.framebuffer_texture(&mask_temp_framebuffer)), + ], + images: &[], + uniforms: &[ + (&self.programs.tile_clip_combine_program.framebuffer_size_uniform, + UniformData::Vec2(mask_texture_size.to_f32().0)), + ], + storage_buffers: &[], + viewport: RectI::new(Vector2I::zero(), mask_texture_size), + options: RenderOptions::default(), + }); + + core.device.end_timer_query(&timer_query); + core.current_timer.as_mut().unwrap().other_times.push(TimerFuture::new(timer_query)); + core.stats.drawcall_count += 2; + + core.allocator.free_framebuffer(mask_temp_framebuffer_id); + } + + fn upload_z_buffer(&mut self, core: &mut RendererCore, z_buffer_map: &DenseTileMap) + -> TextureID { + let z_buffer_texture_id = core.allocator.allocate_texture(&core.device, + z_buffer_map.rect.size(), + TextureFormat::RGBA8, + TextureTag("ZBufferD3D9")); + let z_buffer_texture = core.allocator.get_texture(z_buffer_texture_id); + debug_assert_eq!(z_buffer_map.rect.origin(), Vector2I::default()); + let z_data: &[u8] = z_buffer_map.data.as_byte_slice(); + core.device.upload_to_texture(z_buffer_texture, + z_buffer_map.rect, + TextureDataRef::U8(&z_data)); + z_buffer_texture_id + } + + // Uploads clip tiles from CPU to GPU. + fn upload_clip_tiles(&mut self, core: &mut RendererCore, clips: &[Clip]) -> ClipBufferInfo { + let clip_buffer_id = core.allocator.allocate_buffer::(&core.device, + clips.len() as u64, + BufferTag("ClipD3D9")); + let clip_buffer = core.allocator.get_buffer(clip_buffer_id); + core.device.upload_to_buffer(clip_buffer, 0, clips, BufferTarget::Vertex); + ClipBufferInfo { clip_buffer_id, clip_count: clips.len() as u32 } + } + + fn draw_tiles(&mut self, + core: &mut RendererCore, + tile_count: u32, + tile_vertex_buffer_id: BufferID, + color_texture_0: Option, + blend_mode: BlendMode, + z_buffer_texture_id: TextureID) { + // TODO(pcwalton): Disable blend for solid tiles. + + if tile_count == 0 { + return; + } + + core.stats.total_tile_count += tile_count as usize; + + let needs_readable_framebuffer = blend_mode.needs_readable_framebuffer(); + if needs_readable_framebuffer { + self.copy_alpha_tiles_to_dest_blend_texture(core, tile_count, tile_vertex_buffer_id); + } + + let clear_color = core.clear_color_for_draw_operation(); + let draw_viewport = core.draw_viewport(); + + let timer_query = core.timer_query_cache.alloc(&core.device); + core.device.begin_timer_query(&timer_query); + + let tile_raster_program = &self.programs.tile_program; + + let tile_vertex_buffer = core.allocator.get_buffer(tile_vertex_buffer_id); + let quad_vertex_positions_buffer = core.allocator + .get_buffer(core.quad_vertex_positions_buffer_id); + let quad_vertex_indices_buffer = core.allocator + .get_buffer(core.quad_vertex_indices_buffer_id); + let dest_blend_framebuffer = core.allocator + .get_framebuffer(self.dest_blend_framebuffer_id); + + let (mut textures, mut uniforms) = (vec![], vec![]); + + core.set_uniforms_for_drawing_tiles(&tile_raster_program.common, + &mut textures, + &mut uniforms, + color_texture_0); + + uniforms.push((&tile_raster_program.transform_uniform, + UniformData::Mat4(self.tile_transform(core).to_columns()))); + + if needs_readable_framebuffer { + textures.push((&tile_raster_program.dest_texture, + core.device.framebuffer_texture(dest_blend_framebuffer))); + } + + let z_buffer_texture = core.allocator.get_texture(z_buffer_texture_id); + textures.push((&tile_raster_program.common.z_buffer_texture, z_buffer_texture)); + uniforms.push((&tile_raster_program.common.z_buffer_texture_size_uniform, + UniformData::IVec2(core.device.texture_size(z_buffer_texture).0))); + + let tile_vertex_array = TileVertexArrayD3D9::new(&core.device, + &self.programs.tile_program, + tile_vertex_buffer, + quad_vertex_positions_buffer, + quad_vertex_indices_buffer); + + core.device.draw_elements_instanced(6, tile_count, &RenderState { + target: &core.draw_render_target(), + program: &tile_raster_program.common.program, + vertex_array: &tile_vertex_array.vertex_array, + primitive: Primitive::Triangles, + textures: &textures, + images: &[], + storage_buffers: &[], + uniforms: &uniforms, + viewport: draw_viewport, + options: RenderOptions { + blend: blend_mode.to_blend_state(), + stencil: self.stencil_state(core), + clear_ops: ClearOps { color: clear_color, ..ClearOps::default() }, + ..RenderOptions::default() + }, + }); + + core.device.end_timer_query(&timer_query); + core.current_timer.as_mut().unwrap().composite_times.push(TimerFuture::new(timer_query)); + core.stats.drawcall_count += 1; + + core.preserve_draw_framebuffer(); + } + + fn copy_alpha_tiles_to_dest_blend_texture(&mut self, + core: &mut RendererCore, + tile_count: u32, + vertex_buffer_id: BufferID) { + let draw_viewport = core.draw_viewport(); + + let mut textures = vec![]; + let mut uniforms = vec![ + (&self.programs.tile_copy_program.transform_uniform, + UniformData::Mat4(self.tile_transform(core).to_columns())), + (&self.programs.tile_copy_program.tile_size_uniform, + UniformData::Vec2(F32x2::new(TILE_WIDTH as f32, TILE_HEIGHT as f32))), + ]; + + let draw_framebuffer = match core.draw_render_target() { + RenderTarget::Framebuffer(framebuffer) => framebuffer, + RenderTarget::Default => panic!("Can't copy alpha tiles from default framebuffer!"), + }; + let draw_texture = core.device.framebuffer_texture(&draw_framebuffer); + + textures.push((&self.programs.tile_copy_program.src_texture, draw_texture)); + uniforms.push((&self.programs.tile_copy_program.framebuffer_size_uniform, + UniformData::Vec2(draw_viewport.size().to_f32().0))); + + let quads_vertex_indices_buffer_id = self.quads_vertex_indices_buffer_id + .expect("Where's the quads vertex buffer?"); + let quads_vertex_indices_buffer = core.allocator + .get_buffer(quads_vertex_indices_buffer_id); + let vertex_buffer = core.allocator.get_buffer(vertex_buffer_id); + + let tile_copy_vertex_array = CopyTileVertexArray::new(&core.device, + &self.programs.tile_copy_program, + vertex_buffer, + quads_vertex_indices_buffer); + + let dest_blend_framebuffer = core.allocator + .get_framebuffer(self.dest_blend_framebuffer_id); + + core.device.draw_elements(tile_count * 6, &RenderState { + target: &RenderTarget::Framebuffer(dest_blend_framebuffer), + program: &self.programs.tile_copy_program.program, + vertex_array: &tile_copy_vertex_array.vertex_array, + primitive: Primitive::Triangles, + textures: &textures, + images: &[], + storage_buffers: &[], + uniforms: &uniforms, + viewport: draw_viewport, + options: RenderOptions { + clear_ops: ClearOps { + color: Some(ColorF::new(1.0, 0.0, 0.0, 1.0)), + ..ClearOps::default() + }, + ..RenderOptions::default() + }, + }); + + core.stats.drawcall_count += 1; + } + + fn stencil_state(&self, core: &RendererCore) -> Option { + if !core.renderer_flags.contains(RendererFlags::USE_DEPTH) { + return None; + } + + Some(StencilState { + func: StencilFunc::Equal, + reference: 1, + mask: 1, + write: false, + }) + } + + fn mask_viewport(&self, core: &RendererCore) -> RectI { + let page_count = match core.mask_storage { + Some(ref mask_storage) => mask_storage.allocated_page_count as i32, + None => 0, + }; + let height = MASK_FRAMEBUFFER_HEIGHT * page_count; + RectI::new(Vector2I::default(), vec2i(MASK_FRAMEBUFFER_WIDTH, height)) + } + + fn tile_transform(&self, core: &RendererCore) -> Transform4F { + let draw_viewport = core.draw_viewport().size().to_f32(); + let scale = Vector4F::new(2.0 / draw_viewport.x(), -2.0 / draw_viewport.y(), 1.0, 1.0); + Transform4F::from_scale(scale).translate(Vector4F::new(-1.0, 1.0, 0.0, 1.0)) + } +} + +#[derive(Clone)] +pub(crate) struct TileBatchInfoD3D9 { + pub(crate) tile_count: u32, + pub(crate) z_buffer_id: BufferID, + tile_vertex_buffer_id: BufferID, +} + +#[derive(Clone)] +struct FillBufferInfoD3D9 { + fill_buffer_id: BufferID, + fill_count: u32, +} + +struct TileBufferD3D9 { + tile_vertex_buffer_id: BufferID, +} + +struct ClipBufferInfo { + clip_buffer_id: BufferID, + clip_count: u32, +} diff --git a/renderer/src/gpu/d3d9/shaders.rs b/renderer/src/gpu/d3d9/shaders.rs new file mode 100644 index 00000000..82aabd7d --- /dev/null +++ b/renderer/src/gpu/d3d9/shaders.rs @@ -0,0 +1,441 @@ +// pathfinder/renderer/src/gpu/d3d9/shaders.rs +// +// Copyright © 2020 The Pathfinder Project Developers. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use crate::gpu::shaders::{TILE_INSTANCE_SIZE, TileProgramCommon}; +use pathfinder_gpu::{BufferTarget, Device, VertexAttrClass, VertexAttrDescriptor, VertexAttrType}; +use pathfinder_resources::ResourceLoader; + +const FILL_INSTANCE_SIZE: usize = 12; +const CLIP_TILE_INSTANCE_SIZE: usize = 16; + +pub struct FillVertexArrayD3D9 where D: Device { + pub vertex_array: D::VertexArray, +} + +impl FillVertexArrayD3D9 where D: Device { + pub fn new(device: &D, + fill_program: &FillProgramD3D9, + vertex_buffer: &D::Buffer, + quad_vertex_positions_buffer: &D::Buffer, + quad_vertex_indices_buffer: &D::Buffer) + -> FillVertexArrayD3D9 { + let vertex_array = device.create_vertex_array(); + + let tess_coord_attr = device.get_vertex_attr(&fill_program.program, "TessCoord").unwrap(); + let line_segment_attr = device.get_vertex_attr(&fill_program.program, "LineSegment") + .unwrap(); + let tile_index_attr = device.get_vertex_attr(&fill_program.program, "TileIndex").unwrap(); + + device.bind_buffer(&vertex_array, quad_vertex_positions_buffer, BufferTarget::Vertex); + device.configure_vertex_attr(&vertex_array, &tess_coord_attr, &VertexAttrDescriptor { + size: 2, + class: VertexAttrClass::Int, + attr_type: VertexAttrType::U16, + stride: 4, + offset: 0, + divisor: 0, + buffer_index: 0, + }); + device.bind_buffer(&vertex_array, &vertex_buffer, BufferTarget::Vertex); + device.configure_vertex_attr(&vertex_array, &line_segment_attr, &VertexAttrDescriptor { + size: 4, + class: VertexAttrClass::Int, + attr_type: VertexAttrType::U16, + stride: FILL_INSTANCE_SIZE, + offset: 0, + divisor: 1, + buffer_index: 1, + }); + device.configure_vertex_attr(&vertex_array, &tile_index_attr, &VertexAttrDescriptor { + size: 1, + class: VertexAttrClass::Int, + attr_type: VertexAttrType::I32, + stride: FILL_INSTANCE_SIZE, + offset: 8, + divisor: 1, + buffer_index: 1, + }); + device.bind_buffer(&vertex_array, quad_vertex_indices_buffer, BufferTarget::Index); + + FillVertexArrayD3D9 { vertex_array } + } +} + +pub struct TileVertexArrayD3D9 where D: Device { + pub vertex_array: D::VertexArray, +} + +impl TileVertexArrayD3D9 where D: Device { + pub fn new(device: &D, + tile_program: &TileProgramD3D9, + tile_vertex_buffer: &D::Buffer, + quad_vertex_positions_buffer: &D::Buffer, + quad_vertex_indices_buffer: &D::Buffer) + -> TileVertexArrayD3D9 { + let vertex_array = device.create_vertex_array(); + + let tile_offset_attr = + device.get_vertex_attr(&tile_program.common.program, "TileOffset").unwrap(); + let tile_origin_attr = + device.get_vertex_attr(&tile_program.common.program, "TileOrigin").unwrap(); + let mask_0_tex_coord_attr = + device.get_vertex_attr(&tile_program.common.program, "MaskTexCoord0").unwrap(); + let ctrl_backdrop_attr = + device.get_vertex_attr(&tile_program.common.program, "CtrlBackdrop").unwrap(); + let color_attr = device.get_vertex_attr(&tile_program.common.program, "Color").unwrap(); + let path_index_attr = device.get_vertex_attr(&tile_program.common.program, "PathIndex") + .unwrap(); + + device.bind_buffer(&vertex_array, quad_vertex_positions_buffer, BufferTarget::Vertex); + device.configure_vertex_attr(&vertex_array, &tile_offset_attr, &VertexAttrDescriptor { + size: 2, + class: VertexAttrClass::Int, + attr_type: VertexAttrType::I16, + stride: 4, + offset: 0, + divisor: 0, + buffer_index: 0, + }); + device.bind_buffer(&vertex_array, tile_vertex_buffer, BufferTarget::Vertex); + device.configure_vertex_attr(&vertex_array, &tile_origin_attr, &VertexAttrDescriptor { + size: 2, + class: VertexAttrClass::Int, + attr_type: VertexAttrType::I16, + stride: TILE_INSTANCE_SIZE, + offset: 0, + divisor: 1, + buffer_index: 1, + }); + device.configure_vertex_attr(&vertex_array, &mask_0_tex_coord_attr, &VertexAttrDescriptor { + size: 4, + class: VertexAttrClass::Int, + attr_type: VertexAttrType::U8, + stride: TILE_INSTANCE_SIZE, + offset: 4, + divisor: 1, + buffer_index: 1, + }); + device.configure_vertex_attr(&vertex_array, &path_index_attr, &VertexAttrDescriptor { + size: 1, + class: VertexAttrClass::Int, + attr_type: VertexAttrType::I32, + stride: TILE_INSTANCE_SIZE, + offset: 8, + divisor: 1, + buffer_index: 1, + }); + device.configure_vertex_attr(&vertex_array, &color_attr, &VertexAttrDescriptor { + size: 1, + class: VertexAttrClass::Int, + attr_type: VertexAttrType::I16, + stride: TILE_INSTANCE_SIZE, + offset: 12, + divisor: 1, + buffer_index: 1, + }); + device.configure_vertex_attr(&vertex_array, &ctrl_backdrop_attr, &VertexAttrDescriptor { + size: 2, + class: VertexAttrClass::Int, + attr_type: VertexAttrType::I8, + stride: TILE_INSTANCE_SIZE, + offset: 14, + divisor: 1, + buffer_index: 1, + }); + device.bind_buffer(&vertex_array, quad_vertex_indices_buffer, BufferTarget::Index); + + TileVertexArrayD3D9 { vertex_array } + } +} + +pub struct ClipTileCopyVertexArrayD3D9 where D: Device { + pub vertex_array: D::VertexArray, +} + +impl ClipTileCopyVertexArrayD3D9 where D: Device { + pub fn new(device: &D, + clip_tile_copy_program: &ClipTileCopyProgramD3D9, + vertex_buffer: &D::Buffer, + quad_vertex_positions_buffer: &D::Buffer, + quad_vertex_indices_buffer: &D::Buffer) + -> ClipTileCopyVertexArrayD3D9 { + let vertex_array = device.create_vertex_array(); + + let tile_offset_attr = + device.get_vertex_attr(&clip_tile_copy_program.program, "TileOffset").unwrap(); + let tile_index_attr = + device.get_vertex_attr(&clip_tile_copy_program.program, "TileIndex").unwrap(); + + device.bind_buffer(&vertex_array, quad_vertex_positions_buffer, BufferTarget::Vertex); + device.configure_vertex_attr(&vertex_array, &tile_offset_attr, &VertexAttrDescriptor { + size: 2, + class: VertexAttrClass::Int, + attr_type: VertexAttrType::I16, + stride: 4, + offset: 0, + divisor: 0, + buffer_index: 0, + }); + device.bind_buffer(&vertex_array, &vertex_buffer, BufferTarget::Vertex); + device.configure_vertex_attr(&vertex_array, &tile_index_attr, &VertexAttrDescriptor { + size: 1, + class: VertexAttrClass::Int, + attr_type: VertexAttrType::I32, + stride: CLIP_TILE_INSTANCE_SIZE / 2, + offset: 0, + divisor: 1, + buffer_index: 1, + }); + device.bind_buffer(&vertex_array, quad_vertex_indices_buffer, BufferTarget::Index); + + ClipTileCopyVertexArrayD3D9 { vertex_array } + } +} + +pub struct ClipTileCombineVertexArrayD3D9 where D: Device { + pub vertex_array: D::VertexArray, +} + +impl ClipTileCombineVertexArrayD3D9 where D: Device { + pub fn new(device: &D, + clip_tile_combine_program: &ClipTileCombineProgramD3D9, + vertex_buffer: &D::Buffer, + quad_vertex_positions_buffer: &D::Buffer, + quad_vertex_indices_buffer: &D::Buffer) + -> ClipTileCombineVertexArrayD3D9 { + let vertex_array = device.create_vertex_array(); + + let tile_offset_attr = + device.get_vertex_attr(&clip_tile_combine_program.program, "TileOffset").unwrap(); + let dest_tile_index_attr = + device.get_vertex_attr(&clip_tile_combine_program.program, "DestTileIndex").unwrap(); + let dest_backdrop_attr = + device.get_vertex_attr(&clip_tile_combine_program.program, "DestBackdrop").unwrap(); + let src_tile_index_attr = + device.get_vertex_attr(&clip_tile_combine_program.program, "SrcTileIndex").unwrap(); + let src_backdrop_attr = + device.get_vertex_attr(&clip_tile_combine_program.program, "SrcBackdrop").unwrap(); + + device.bind_buffer(&vertex_array, quad_vertex_positions_buffer, BufferTarget::Vertex); + device.configure_vertex_attr(&vertex_array, &tile_offset_attr, &VertexAttrDescriptor { + size: 2, + class: VertexAttrClass::Int, + attr_type: VertexAttrType::I16, + stride: 4, + offset: 0, + divisor: 0, + buffer_index: 0, + }); + device.bind_buffer(&vertex_array, &vertex_buffer, BufferTarget::Vertex); + device.configure_vertex_attr(&vertex_array, &dest_tile_index_attr, &VertexAttrDescriptor { + size: 1, + class: VertexAttrClass::Int, + attr_type: VertexAttrType::I32, + stride: CLIP_TILE_INSTANCE_SIZE, + offset: 0, + divisor: 1, + buffer_index: 1, + }); + device.configure_vertex_attr(&vertex_array, &dest_backdrop_attr, &VertexAttrDescriptor { + size: 1, + class: VertexAttrClass::Int, + attr_type: VertexAttrType::I32, + stride: CLIP_TILE_INSTANCE_SIZE, + offset: 4, + divisor: 1, + buffer_index: 1, + }); + device.configure_vertex_attr(&vertex_array, &src_tile_index_attr, &VertexAttrDescriptor { + size: 1, + class: VertexAttrClass::Int, + attr_type: VertexAttrType::I32, + stride: CLIP_TILE_INSTANCE_SIZE, + offset: 8, + divisor: 1, + buffer_index: 1, + }); + device.configure_vertex_attr(&vertex_array, &src_backdrop_attr, &VertexAttrDescriptor { + size: 1, + class: VertexAttrClass::Int, + attr_type: VertexAttrType::I32, + stride: CLIP_TILE_INSTANCE_SIZE, + offset: 12, + divisor: 1, + buffer_index: 1, + }); + device.bind_buffer(&vertex_array, quad_vertex_indices_buffer, BufferTarget::Index); + + ClipTileCombineVertexArrayD3D9 { vertex_array } + } +} + +pub struct CopyTileVertexArray where D: Device { + pub vertex_array: D::VertexArray, +} + +impl CopyTileVertexArray where D: Device { + pub fn new(device: &D, + copy_tile_program: &CopyTileProgram, + copy_tile_vertex_buffer: &D::Buffer, + quads_vertex_indices_buffer: &D::Buffer) + -> CopyTileVertexArray { + let vertex_array = device.create_vertex_array(); + + let tile_position_attr = + device.get_vertex_attr(©_tile_program.program, "TilePosition").unwrap(); + + device.bind_buffer(&vertex_array, copy_tile_vertex_buffer, BufferTarget::Vertex); + device.configure_vertex_attr(&vertex_array, &tile_position_attr, &VertexAttrDescriptor { + size: 2, + class: VertexAttrClass::Int, + attr_type: VertexAttrType::I16, + stride: TILE_INSTANCE_SIZE, + offset: 0, + divisor: 0, + buffer_index: 0, + }); + device.bind_buffer(&vertex_array, quads_vertex_indices_buffer, BufferTarget::Index); + + CopyTileVertexArray { vertex_array } + } +} + +pub struct FillProgramD3D9 where D: Device { + pub program: D::Program, + pub framebuffer_size_uniform: D::Uniform, + pub tile_size_uniform: D::Uniform, + pub area_lut_texture: D::TextureParameter, +} + +impl FillProgramD3D9 where D: Device { + fn new(device: &D, resources: &dyn ResourceLoader) -> FillProgramD3D9 { + let program = device.create_raster_program(resources, "d3d9/fill"); + let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize"); + let tile_size_uniform = device.get_uniform(&program, "TileSize"); + let area_lut_texture = device.get_texture_parameter(&program, "AreaLUT"); + FillProgramD3D9 { + program, + framebuffer_size_uniform, + tile_size_uniform, + area_lut_texture, + } + } +} + +pub struct TileProgramD3D9 where D: Device { + pub common: TileProgramCommon, + pub dest_texture: D::TextureParameter, + pub transform_uniform: D::Uniform, +} + +impl TileProgramD3D9 where D: Device { + fn new(device: &D, resources: &dyn ResourceLoader) -> TileProgramD3D9 { + let program = device.create_raster_program(resources, "d3d9/tile"); + let dest_texture = device.get_texture_parameter(&program, "DestTexture"); + let transform_uniform = device.get_uniform(&program, "Transform"); + let common = TileProgramCommon::new(device, program); + TileProgramD3D9 { common, dest_texture, transform_uniform } + } +} + +pub struct ClipTileCombineProgramD3D9 where D: Device { + pub program: D::Program, + pub src_texture: D::TextureParameter, + pub framebuffer_size_uniform: D::Uniform, +} + +impl ClipTileCombineProgramD3D9 where D: Device { + pub fn new(device: &D, resources: &dyn ResourceLoader) -> ClipTileCombineProgramD3D9 { + let program = device.create_raster_program(resources, "d3d9/tile_clip_combine"); + let src_texture = device.get_texture_parameter(&program, "Src"); + let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize"); + ClipTileCombineProgramD3D9 { program, src_texture, framebuffer_size_uniform } + } +} + +pub struct ClipTileCopyProgramD3D9 where D: Device { + pub program: D::Program, + pub src_texture: D::TextureParameter, + pub framebuffer_size_uniform: D::Uniform, +} + +impl ClipTileCopyProgramD3D9 where D: Device { + pub fn new(device: &D, resources: &dyn ResourceLoader) -> ClipTileCopyProgramD3D9 { + let program = device.create_raster_program(resources, "d3d9/tile_clip_copy"); + let src_texture = device.get_texture_parameter(&program, "Src"); + let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize"); + ClipTileCopyProgramD3D9 { program, src_texture, framebuffer_size_uniform } + } +} + +pub struct CopyTileProgram where D: Device { + pub program: D::Program, + pub transform_uniform: D::Uniform, + pub tile_size_uniform: D::Uniform, + pub framebuffer_size_uniform: D::Uniform, + pub src_texture: D::TextureParameter, +} + +impl CopyTileProgram where D: Device { + pub fn new(device: &D, resources: &dyn ResourceLoader) -> CopyTileProgram { + let program = device.create_raster_program(resources, "d3d9/tile_copy"); + let transform_uniform = device.get_uniform(&program, "Transform"); + let tile_size_uniform = device.get_uniform(&program, "TileSize"); + let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize"); + let src_texture = device.get_texture_parameter(&program, "Src"); + CopyTileProgram { + program, + transform_uniform, + tile_size_uniform, + framebuffer_size_uniform, + src_texture, + } + } +} + +pub struct D3D9Programs where D: Device { + pub fill_program: FillProgramD3D9, + pub tile_program: TileProgramD3D9, + pub tile_clip_combine_program: ClipTileCombineProgramD3D9, + pub tile_clip_copy_program: ClipTileCopyProgramD3D9, + pub tile_copy_program: CopyTileProgram, +} + +impl D3D9Programs where D: Device { + pub fn new(device: &D, resources: &dyn ResourceLoader) -> D3D9Programs { + D3D9Programs { + fill_program: FillProgramD3D9::new(device, resources), + tile_program: TileProgramD3D9::new(device, resources), + tile_clip_combine_program: ClipTileCombineProgramD3D9::new(device, resources), + tile_clip_copy_program: ClipTileCopyProgramD3D9::new(device, resources), + tile_copy_program: CopyTileProgram::new(device, resources), + } + } +} + +pub struct ProgramsD3D9 where D: Device { + pub fill_program: FillProgramD3D9, + pub tile_program: TileProgramD3D9, + pub tile_clip_copy_program: ClipTileCopyProgramD3D9, + pub tile_clip_combine_program: ClipTileCombineProgramD3D9, + pub tile_copy_program: CopyTileProgram, +} + +impl ProgramsD3D9 where D: Device { + pub fn new(device: &D, resources: &dyn ResourceLoader) -> ProgramsD3D9 { + ProgramsD3D9 { + fill_program: FillProgramD3D9::new(device, resources), + tile_program: TileProgramD3D9::new(device, resources), + tile_clip_copy_program: ClipTileCopyProgramD3D9::new(device, resources), + tile_clip_combine_program: ClipTileCombineProgramD3D9::new(device, resources), + tile_copy_program: CopyTileProgram::new(device, resources), + } + } +} diff --git a/renderer/src/gpu/shaders.rs b/renderer/src/gpu/shaders.rs index ee04ff1d..84bd0482 100644 --- a/renderer/src/gpu/shaders.rs +++ b/renderer/src/gpu/shaders.rs @@ -8,20 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use crate::gpu::options::RendererOptions; -use crate::gpu::renderer::{MASK_TILES_ACROSS, MASK_TILES_DOWN}; -use crate::tiles::{TILE_HEIGHT, TILE_WIDTH}; -use pathfinder_gpu::{BufferTarget, BufferUploadMode, ComputeDimensions, Device, FeatureLevel}; -use pathfinder_gpu::{VertexAttrClass, VertexAttrDescriptor, VertexAttrType}; +use pathfinder_gpu::{BufferTarget, BufferUploadMode, Device, VertexAttrClass}; +use pathfinder_gpu::{VertexAttrDescriptor, VertexAttrType}; use pathfinder_resources::ResourceLoader; // TODO(pcwalton): Replace with `mem::size_of` calls? -pub(crate) const TILE_INSTANCE_SIZE: usize = 12; -const FILL_INSTANCE_SIZE: usize = 8; -const CLIP_TILE_INSTANCE_SIZE: usize = 8; - -pub const MAX_FILLS_PER_BATCH: usize = 0x10000; -pub const MAX_TILES_PER_BATCH: usize = MASK_TILES_ACROSS as usize * MASK_TILES_DOWN as usize; +pub(crate) const TILE_INSTANCE_SIZE: usize = 16; pub struct BlitVertexArray where D: Device { pub vertex_array: D::VertexArray, @@ -52,6 +44,25 @@ impl BlitVertexArray where D: Device { } } +pub struct VertexArraysCore where D: Device { + pub blit_vertex_array: BlitVertexArray, +} + +impl VertexArraysCore where D: Device { + pub fn new(device: &D, + programs: &ProgramsCore, + quad_vertex_positions_buffer: &D::Buffer, + quad_vertex_indices_buffer: &D::Buffer) + -> VertexArraysCore { + VertexArraysCore { + blit_vertex_array: BlitVertexArray::new(device, + &programs.blit_program, + quad_vertex_positions_buffer, + quad_vertex_indices_buffer), + } + } +} + pub struct ClearVertexArray where D: Device { pub vertex_array: D::VertexArray, } @@ -81,288 +92,32 @@ impl ClearVertexArray where D: Device { } } -pub struct FillVertexArray where D: Device { - pub vertex_array: D::VertexArray, -} - -impl FillVertexArray -where - D: Device, -{ - pub fn new( - device: &D, - fill_program: &FillRasterProgram, - vertex_buffer: &D::Buffer, - quad_vertex_positions_buffer: &D::Buffer, - quad_vertex_indices_buffer: &D::Buffer, - ) -> FillVertexArray { - let vertex_array = device.create_vertex_array(); - - let tess_coord_attr = device.get_vertex_attr(&fill_program.program, "TessCoord").unwrap(); - let from_px_attr = device.get_vertex_attr(&fill_program.program, "FromPx").unwrap(); - let to_px_attr = device.get_vertex_attr(&fill_program.program, "ToPx").unwrap(); - let from_subpx_attr = device.get_vertex_attr(&fill_program.program, "FromSubpx").unwrap(); - let to_subpx_attr = device.get_vertex_attr(&fill_program.program, "ToSubpx").unwrap(); - let tile_index_attr = device.get_vertex_attr(&fill_program.program, "TileIndex").unwrap(); - - device.bind_buffer(&vertex_array, quad_vertex_positions_buffer, BufferTarget::Vertex); - device.configure_vertex_attr(&vertex_array, &tess_coord_attr, &VertexAttrDescriptor { - size: 2, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::U16, - stride: 4, - offset: 0, - divisor: 0, - buffer_index: 0, - }); - device.bind_buffer(&vertex_array, &vertex_buffer, BufferTarget::Vertex); - device.configure_vertex_attr(&vertex_array, &from_subpx_attr, &VertexAttrDescriptor { - size: 2, - class: VertexAttrClass::FloatNorm, - attr_type: VertexAttrType::U8, - stride: FILL_INSTANCE_SIZE, - offset: 0, - divisor: 1, - buffer_index: 1, - }); - device.configure_vertex_attr(&vertex_array, &to_subpx_attr, &VertexAttrDescriptor { - size: 2, - class: VertexAttrClass::FloatNorm, - attr_type: VertexAttrType::U8, - stride: FILL_INSTANCE_SIZE, - offset: 2, - divisor: 1, - buffer_index: 1, - }); - device.configure_vertex_attr(&vertex_array, &from_px_attr, &VertexAttrDescriptor { - size: 1, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::U8, - stride: FILL_INSTANCE_SIZE, - offset: 4, - divisor: 1, - buffer_index: 1, - }); - device.configure_vertex_attr(&vertex_array, &to_px_attr, &VertexAttrDescriptor { - size: 1, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::U8, - stride: FILL_INSTANCE_SIZE, - offset: 5, - divisor: 1, - buffer_index: 1, - }); - device.configure_vertex_attr(&vertex_array, &tile_index_attr, &VertexAttrDescriptor { - size: 1, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::U16, - stride: FILL_INSTANCE_SIZE, - offset: 6, - divisor: 1, - buffer_index: 1, - }); - device.bind_buffer(&vertex_array, quad_vertex_indices_buffer, BufferTarget::Index); - - FillVertexArray { vertex_array } - } -} - -pub struct TileVertexArray where D: Device { - pub vertex_array: D::VertexArray, -} - -impl TileVertexArray where D: Device { - pub fn new(device: &D, - tile_program: &TileProgram, - tile_vertex_buffer: &D::Buffer, - quad_vertex_positions_buffer: &D::Buffer, - quad_vertex_indices_buffer: &D::Buffer) - -> TileVertexArray { - let vertex_array = device.create_vertex_array(); - - let tile_offset_attr = - device.get_vertex_attr(&tile_program.program, "TileOffset").unwrap(); - let tile_origin_attr = - device.get_vertex_attr(&tile_program.program, "TileOrigin").unwrap(); - let mask_0_tex_coord_attr = - device.get_vertex_attr(&tile_program.program, "MaskTexCoord0").unwrap(); - let mask_backdrop_attr = - device.get_vertex_attr(&tile_program.program, "MaskBackdrop").unwrap(); - let color_attr = device.get_vertex_attr(&tile_program.program, "Color").unwrap(); - let tile_ctrl_attr = device.get_vertex_attr(&tile_program.program, "TileCtrl").unwrap(); - - device.bind_buffer(&vertex_array, quad_vertex_positions_buffer, BufferTarget::Vertex); - device.configure_vertex_attr(&vertex_array, &tile_offset_attr, &VertexAttrDescriptor { - size: 2, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::I16, - stride: 4, - offset: 0, - divisor: 0, - buffer_index: 0, - }); - device.bind_buffer(&vertex_array, tile_vertex_buffer, BufferTarget::Vertex); - device.configure_vertex_attr(&vertex_array, &tile_origin_attr, &VertexAttrDescriptor { - size: 2, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::I16, - stride: TILE_INSTANCE_SIZE, - offset: 0, - divisor: 1, - buffer_index: 1, - }); - device.configure_vertex_attr(&vertex_array, &mask_0_tex_coord_attr, &VertexAttrDescriptor { - size: 2, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::U8, - stride: TILE_INSTANCE_SIZE, - offset: 4, - divisor: 1, - buffer_index: 1, - }); - device.configure_vertex_attr(&vertex_array, &mask_backdrop_attr, &VertexAttrDescriptor { - size: 2, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::I8, - stride: TILE_INSTANCE_SIZE, - offset: 6, - divisor: 1, - buffer_index: 1, - }); - device.configure_vertex_attr(&vertex_array, &color_attr, &VertexAttrDescriptor { - size: 1, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::I16, - stride: TILE_INSTANCE_SIZE, - offset: 8, - divisor: 1, - buffer_index: 1, - }); - device.configure_vertex_attr(&vertex_array, &tile_ctrl_attr, &VertexAttrDescriptor { - size: 1, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::I16, - stride: TILE_INSTANCE_SIZE, - offset: 10, - divisor: 1, - buffer_index: 1, - }); - device.bind_buffer(&vertex_array, quad_vertex_indices_buffer, BufferTarget::Index); - - TileVertexArray { vertex_array } - } -} - -pub struct CopyTileVertexArray where D: Device { - pub vertex_array: D::VertexArray, -} - -impl CopyTileVertexArray where D: Device { - pub fn new( - device: &D, - copy_tile_program: &CopyTileProgram, - copy_tile_vertex_buffer: &D::Buffer, - quads_vertex_indices_buffer: &D::Buffer, - ) -> CopyTileVertexArray { - let vertex_array = device.create_vertex_array(); - - let tile_position_attr = - device.get_vertex_attr(©_tile_program.program, "TilePosition").unwrap(); - - device.bind_buffer(&vertex_array, copy_tile_vertex_buffer, BufferTarget::Vertex); - device.configure_vertex_attr(&vertex_array, &tile_position_attr, &VertexAttrDescriptor { - size: 2, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::I16, - stride: TILE_INSTANCE_SIZE, - offset: 0, - divisor: 0, - buffer_index: 0, - }); - device.bind_buffer(&vertex_array, quads_vertex_indices_buffer, BufferTarget::Index); - - CopyTileVertexArray { vertex_array } - } -} - -pub struct ClipTileVertexArray where D: Device { - pub vertex_array: D::VertexArray, - pub vertex_buffer: D::Buffer, -} - -impl ClipTileVertexArray where D: Device { - pub fn new(device: &D, - clip_tile_program: &ClipTileProgram, - quad_vertex_positions_buffer: &D::Buffer, - quad_vertex_indices_buffer: &D::Buffer) - -> ClipTileVertexArray { - let vertex_array = device.create_vertex_array(); - let vertex_buffer = device.create_buffer(BufferUploadMode::Dynamic); - - let tile_offset_attr = - device.get_vertex_attr(&clip_tile_program.program, "TileOffset").unwrap(); - let dest_tile_origin_attr = - device.get_vertex_attr(&clip_tile_program.program, "DestTileOrigin").unwrap(); - let src_tile_origin_attr = - device.get_vertex_attr(&clip_tile_program.program, "SrcTileOrigin").unwrap(); - let src_backdrop_attr = - device.get_vertex_attr(&clip_tile_program.program, "SrcBackdrop").unwrap(); - - device.bind_buffer(&vertex_array, quad_vertex_positions_buffer, BufferTarget::Vertex); - device.configure_vertex_attr(&vertex_array, &tile_offset_attr, &VertexAttrDescriptor { - size: 2, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::I16, - stride: 4, - offset: 0, - divisor: 0, - buffer_index: 0, - }); - device.bind_buffer(&vertex_array, &vertex_buffer, BufferTarget::Vertex); - device.configure_vertex_attr(&vertex_array, &dest_tile_origin_attr, &VertexAttrDescriptor { - size: 2, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::U8, - stride: CLIP_TILE_INSTANCE_SIZE, - offset: 0, - divisor: 1, - buffer_index: 1, - }); - device.configure_vertex_attr(&vertex_array, &src_tile_origin_attr, &VertexAttrDescriptor { - size: 2, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::U8, - stride: CLIP_TILE_INSTANCE_SIZE, - offset: 2, - divisor: 1, - buffer_index: 1, - }); - device.configure_vertex_attr(&vertex_array, &src_backdrop_attr, &VertexAttrDescriptor { - size: 1, - class: VertexAttrClass::Int, - attr_type: VertexAttrType::I8, - stride: CLIP_TILE_INSTANCE_SIZE, - offset: 4, - divisor: 1, - buffer_index: 1, - }); - device.bind_buffer(&vertex_array, quad_vertex_indices_buffer, BufferTarget::Index); - - ClipTileVertexArray { vertex_array, vertex_buffer } - } -} - - pub struct BlitProgram where D: Device { pub program: D::Program, + pub dest_rect_uniform: D::Uniform, + pub framebuffer_size_uniform: D::Uniform, pub src_texture: D::TextureParameter, } impl BlitProgram where D: Device { pub fn new(device: &D, resources: &dyn ResourceLoader) -> BlitProgram { let program = device.create_raster_program(resources, "blit"); + let dest_rect_uniform = device.get_uniform(&program, "DestRect"); + let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize"); let src_texture = device.get_texture_parameter(&program, "Src"); - BlitProgram { program, src_texture } + BlitProgram { program, dest_rect_uniform, framebuffer_size_uniform, src_texture } + } +} + +pub struct ProgramsCore where D: Device { + pub blit_program: BlitProgram, +} + +impl ProgramsCore where D: Device { + pub fn new(device: &D, resources: &dyn ResourceLoader) -> ProgramsCore { + ProgramsCore { + blit_program: BlitProgram::new(device, resources), + } } } @@ -383,211 +138,73 @@ impl ClearProgram where D: Device { } } -pub enum FillProgram where D: Device { - Raster(FillRasterProgram), - Compute(FillComputeProgram), -} - -impl FillProgram where D: Device { - pub fn new(device: &D, resources: &dyn ResourceLoader, options: &RendererOptions) - -> FillProgram { - match (options.no_compute, device.feature_level()) { - (false, FeatureLevel::D3D11) => { - FillProgram::Compute(FillComputeProgram::new(device, resources)) - } - (_, FeatureLevel::D3D10) | (true, _) => { - FillProgram::Raster(FillRasterProgram::new(device, resources)) - } - } - } -} - -pub struct FillRasterProgram where D: Device { +pub struct TileProgramCommon where D: Device { pub program: D::Program, - pub framebuffer_size_uniform: D::Uniform, - pub tile_size_uniform: D::Uniform, - pub area_lut_texture: D::TextureParameter, -} - -impl FillRasterProgram where D: Device { - pub fn new(device: &D, resources: &dyn ResourceLoader) -> FillRasterProgram { - let program = device.create_raster_program(resources, "fill"); - let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize"); - let tile_size_uniform = device.get_uniform(&program, "TileSize"); - let area_lut_texture = device.get_texture_parameter(&program, "AreaLUT"); - FillRasterProgram { - program, - framebuffer_size_uniform, - tile_size_uniform, - area_lut_texture, - } - } -} - -pub struct FillComputeProgram where D: Device { - pub program: D::Program, - pub dest_image: D::ImageParameter, - pub area_lut_texture: D::TextureParameter, - pub first_tile_index_uniform: D::Uniform, - pub fills_storage_buffer: D::StorageBuffer, - pub next_fills_storage_buffer: D::StorageBuffer, - pub fill_tile_map_storage_buffer: D::StorageBuffer, -} - -impl FillComputeProgram where D: Device { - pub fn new(device: &D, resources: &dyn ResourceLoader) -> FillComputeProgram { - let mut program = device.create_compute_program(resources, "fill"); - let local_size = ComputeDimensions { x: TILE_WIDTH, y: TILE_HEIGHT / 4, z: 1 }; - device.set_compute_program_local_size(&mut program, local_size); - - let dest_image = device.get_image_parameter(&program, "Dest"); - let area_lut_texture = device.get_texture_parameter(&program, "AreaLUT"); - let first_tile_index_uniform = device.get_uniform(&program, "FirstTileIndex"); - let fills_storage_buffer = device.get_storage_buffer(&program, "Fills", 0); - let next_fills_storage_buffer = device.get_storage_buffer(&program, "NextFills", 1); - let fill_tile_map_storage_buffer = device.get_storage_buffer(&program, "FillTileMap", 2); - - FillComputeProgram { - program, - dest_image, - area_lut_texture, - first_tile_index_uniform, - fills_storage_buffer, - next_fills_storage_buffer, - fill_tile_map_storage_buffer, - } - } -} - -pub struct TileProgram where D: Device { - pub program: D::Program, - pub transform_uniform: D::Uniform, pub tile_size_uniform: D::Uniform, pub texture_metadata_texture: D::TextureParameter, pub texture_metadata_size_uniform: D::Uniform, - pub dest_texture: D::TextureParameter, + pub z_buffer_texture: D::TextureParameter, + pub z_buffer_texture_size_uniform: D::Uniform, pub color_texture_0: D::TextureParameter, pub color_texture_size_0_uniform: D::Uniform, pub color_texture_1: D::TextureParameter, pub mask_texture_0: D::TextureParameter, pub mask_texture_size_0_uniform: D::Uniform, pub gamma_lut_texture: D::TextureParameter, - pub filter_params_0_uniform: D::Uniform, - pub filter_params_1_uniform: D::Uniform, - pub filter_params_2_uniform: D::Uniform, pub framebuffer_size_uniform: D::Uniform, - pub ctrl_uniform: D::Uniform, } -impl TileProgram where D: Device { - pub fn new(device: &D, resources: &dyn ResourceLoader) -> TileProgram { - let program = device.create_raster_program(resources, "tile"); - let transform_uniform = device.get_uniform(&program, "Transform"); +impl TileProgramCommon where D: Device { + pub(crate) fn new(device: &D, program: D::Program) -> TileProgramCommon { let tile_size_uniform = device.get_uniform(&program, "TileSize"); let texture_metadata_texture = device.get_texture_parameter(&program, "TextureMetadata"); let texture_metadata_size_uniform = device.get_uniform(&program, "TextureMetadataSize"); - let dest_texture = device.get_texture_parameter(&program, "DestTexture"); + let z_buffer_texture = device.get_texture_parameter(&program, "ZBuffer"); + let z_buffer_texture_size_uniform = device.get_uniform(&program, "ZBufferSize"); let color_texture_0 = device.get_texture_parameter(&program, "ColorTexture0"); let color_texture_size_0_uniform = device.get_uniform(&program, "ColorTextureSize0"); let color_texture_1 = device.get_texture_parameter(&program, "ColorTexture1"); let mask_texture_0 = device.get_texture_parameter(&program, "MaskTexture0"); let mask_texture_size_0_uniform = device.get_uniform(&program, "MaskTextureSize0"); let gamma_lut_texture = device.get_texture_parameter(&program, "GammaLUT"); - let filter_params_0_uniform = device.get_uniform(&program, "FilterParams0"); - let filter_params_1_uniform = device.get_uniform(&program, "FilterParams1"); - let filter_params_2_uniform = device.get_uniform(&program, "FilterParams2"); let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize"); - let ctrl_uniform = device.get_uniform(&program, "Ctrl"); - TileProgram { + + TileProgramCommon { program, - transform_uniform, tile_size_uniform, texture_metadata_texture, texture_metadata_size_uniform, - dest_texture, + z_buffer_texture, + z_buffer_texture_size_uniform, color_texture_0, color_texture_size_0_uniform, color_texture_1, mask_texture_0, mask_texture_size_0_uniform, gamma_lut_texture, - filter_params_0_uniform, - filter_params_1_uniform, - filter_params_2_uniform, framebuffer_size_uniform, - ctrl_uniform, } } } -pub struct CopyTileProgram where D: Device { - pub program: D::Program, - pub transform_uniform: D::Uniform, - pub tile_size_uniform: D::Uniform, - pub framebuffer_size_uniform: D::Uniform, - pub src_texture: D::TextureParameter, -} - -impl CopyTileProgram where D: Device { - pub fn new(device: &D, resources: &dyn ResourceLoader) -> CopyTileProgram { - let program = device.create_raster_program(resources, "tile_copy"); - let transform_uniform = device.get_uniform(&program, "Transform"); - let tile_size_uniform = device.get_uniform(&program, "TileSize"); - let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize"); - let src_texture = device.get_texture_parameter(&program, "Src"); - CopyTileProgram { - program, - transform_uniform, - tile_size_uniform, - framebuffer_size_uniform, - src_texture, - } - } -} - -pub struct ClipTileProgram where D: Device { - pub program: D::Program, - pub src_texture: D::TextureParameter, -} - -impl ClipTileProgram where D: Device { - pub fn new(device: &D, resources: &dyn ResourceLoader) -> ClipTileProgram { - let program = device.create_raster_program(resources, "tile_clip"); - let src_texture = device.get_texture_parameter(&program, "Src"); - ClipTileProgram { program, src_texture } - } -} - -pub struct StencilProgram -where - D: Device, -{ +pub struct StencilProgram where D: Device { pub program: D::Program, } -impl StencilProgram -where - D: Device, -{ +impl StencilProgram where D: Device { pub fn new(device: &D, resources: &dyn ResourceLoader) -> StencilProgram { let program = device.create_raster_program(resources, "stencil"); StencilProgram { program } } } -pub struct StencilVertexArray -where - D: Device, -{ +pub struct StencilVertexArray where D: Device { pub vertex_array: D::VertexArray, pub vertex_buffer: D::Buffer, pub index_buffer: D::Buffer, } -impl StencilVertexArray -where - D: Device, -{ +impl StencilVertexArray where D: Device { pub fn new(device: &D, stencil_program: &StencilProgram) -> StencilVertexArray { let vertex_array = device.create_vertex_array(); let vertex_buffer = device.create_buffer(BufferUploadMode::Static); @@ -628,17 +245,11 @@ impl ReprojectionProgram where D: Device { } } -pub struct ReprojectionVertexArray -where - D: Device, -{ +pub struct ReprojectionVertexArray where D: Device { pub vertex_array: D::VertexArray, } -impl ReprojectionVertexArray -where - D: Device, -{ +impl ReprojectionVertexArray where D: Device { pub fn new( device: &D, reprojection_program: &ReprojectionProgram, diff --git a/resources/shaders/gl3/fill.fs.glsl b/resources/shaders/gl3/d3d9/fill.fs.glsl similarity index 100% rename from resources/shaders/gl3/fill.fs.glsl rename to resources/shaders/gl3/d3d9/fill.fs.glsl diff --git a/resources/shaders/gl3/d3d9/fill.vs.glsl b/resources/shaders/gl3/d3d9/fill.vs.glsl new file mode 100644 index 00000000..b6e3ad45 --- /dev/null +++ b/resources/shaders/gl3/d3d9/fill.vs.glsl @@ -0,0 +1,86 @@ +#version {{version}} +// Automatically generated from files in pathfinder/shaders/. Do not edit! + + + + + + + + + + + + +#extension GL_GOOGLE_include_directive : enable + +precision highp float; + + + + + +uniform vec2 uFramebufferSize; +uniform vec2 uTileSize; + +in uvec2 aTessCoord; +in uvec4 aLineSegment; +in int aTileIndex; + +out vec2 vFrom; +out vec2 vTo; + +vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth, vec2 tileSize){ + uint tilesPerRow = uint(stencilTextureWidth / tileSize . x); + uvec2 tileOffset = uvec2(tileIndex % tilesPerRow, tileIndex / tilesPerRow); + return vec2(tileOffset)* tileSize * vec2(1.0, 0.25); +} + +vec4 computeVertexPosition(uint tileIndex, + uvec2 tessCoord, + uvec4 packedLineSegment, + vec2 tileSize, + vec2 framebufferSize, + out vec2 outFrom, + out vec2 outTo){ + vec2 tileOrigin = computeTileOffset(uint(tileIndex), framebufferSize . x, tileSize); + + vec4 lineSegment = vec4(packedLineSegment)/ 256.0; + vec2 from = lineSegment . xy, to = lineSegment . zw; + + vec2 position; + if(tessCoord . x == 0u) + position . x = floor(min(from . x, to . x)); + else + position . x = ceil(max(from . x, to . x)); + if(tessCoord . y == 0u) + position . y = floor(min(from . y, to . y)); + else + position . y = tileSize . y; + position . y = floor(position . y * 0.25); + + + + + + vec2 offset = vec2(0.0, 1.5)- position * vec2(1.0, 4.0); + outFrom = from + offset; + outTo = to + offset; + + vec2 globalPosition =(tileOrigin + position)/ framebufferSize * 2.0 - 1.0; + + + + return vec4(globalPosition, 0.0, 1.0); +} + +void main(){ + gl_Position = computeVertexPosition(uint(aTileIndex), + aTessCoord, + aLineSegment, + uTileSize, + uFramebufferSize, + vFrom, + vTo); +} + diff --git a/resources/shaders/gl4/tile.fs.glsl b/resources/shaders/gl3/d3d9/tile.fs.glsl similarity index 86% rename from resources/shaders/gl4/tile.fs.glsl rename to resources/shaders/gl3/d3d9/tile.fs.glsl index 33815bd9..ea281c03 100644 --- a/resources/shaders/gl4/tile.fs.glsl +++ b/resources/shaders/gl3/d3d9/tile.fs.glsl @@ -12,27 +12,6 @@ - - - - - - - - - - - - - - - - - - - - - #extension GL_GOOGLE_include_directive : enable precision highp float; @@ -83,24 +62,37 @@ precision highp float; -uniform sampler2D uColorTexture0; -uniform sampler2D uMaskTexture0; -uniform sampler2D uDestTexture; -uniform sampler2D uGammaLUT; -uniform vec2 uColorTextureSize0; -uniform vec2 uMaskTextureSize0; -uniform vec4 uFilterParams0; -uniform vec4 uFilterParams1; -uniform vec4 uFilterParams2; -uniform vec2 uFramebufferSize; -uniform int uCtrl; -in vec3 vMaskTexCoord0; -in vec2 vColorTexCoord0; -in vec4 vBaseColor; -in float vTileCtrl; -out vec4 oFragColor; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -567,27 +559,42 @@ float sampleMask(float maskAlpha, -void calculateColor(int tileCtrl, int ctrl){ +vec4 calculateColor(vec2 fragCoord, + sampler2D colorTexture0, + sampler2D maskTexture0, + sampler2D destTexture, + sampler2D gammaLUT, + vec2 colorTextureSize0, + vec2 maskTextureSize0, + vec4 filterParams0, + vec4 filterParams1, + vec4 filterParams2, + vec2 framebufferSize, + int ctrl, + vec3 maskTexCoord0, + vec2 colorTexCoord0, + vec4 baseColor, + int tileCtrl){ int maskCtrl0 =(tileCtrl >> 0)& 0x3; float maskAlpha = 1.0; - maskAlpha = sampleMask(maskAlpha, uMaskTexture0, uMaskTextureSize0, vMaskTexCoord0, maskCtrl0); + maskAlpha = sampleMask(maskAlpha, maskTexture0, maskTextureSize0, maskTexCoord0, maskCtrl0); - vec4 color = vBaseColor; + vec4 color = baseColor; int color0Combine =(ctrl >> 6)& 0x3; if(color0Combine != 0){ int color0Filter =(ctrl >> 4)& 0x3; - vec4 color0 = filterColor(vColorTexCoord0, - uColorTexture0, - uGammaLUT, - uColorTextureSize0, - gl_FragCoord . xy, - uFramebufferSize, - uFilterParams0, - uFilterParams1, - uFilterParams2, + vec4 color0 = filterColor(colorTexCoord0, + colorTexture0, + gammaLUT, + colorTextureSize0, + fragCoord, + framebufferSize, + filterParams0, + filterParams1, + filterParams2, color0Filter); color = combineColor0(color, color0, color0Combine); } @@ -597,18 +604,53 @@ void calculateColor(int tileCtrl, int ctrl){ int compositeOp =(ctrl >> 8)& 0xf; - color = composite(color, uDestTexture, uFramebufferSize, gl_FragCoord . xy, compositeOp); + color = composite(color, destTexture, framebufferSize, fragCoord, compositeOp); color . rgb *= color . a; - oFragColor = color; + return color; } +uniform sampler2D uColorTexture0; +uniform sampler2D uMaskTexture0; +uniform sampler2D uDestTexture; +uniform sampler2D uGammaLUT; +uniform vec2 uColorTextureSize0; +uniform vec2 uMaskTextureSize0; +uniform vec2 uFramebufferSize; + +in vec3 vMaskTexCoord0; +in vec2 vColorTexCoord0; +in vec4 vBaseColor; +in float vTileCtrl; +in vec4 vFilterParams0; +in vec4 vFilterParams1; +in vec4 vFilterParams2; +in float vCtrl; + +out vec4 oFragColor; + + void main(){ - calculateColor(int(vTileCtrl), uCtrl); + oFragColor = calculateColor(gl_FragCoord . xy, + uColorTexture0, + uMaskTexture0, + uDestTexture, + uGammaLUT, + uColorTextureSize0, + uMaskTextureSize0, + vFilterParams0, + vFilterParams1, + vFilterParams2, + uFramebufferSize, + int(vCtrl), + vMaskTexCoord0, + vColorTexCoord0, + vBaseColor, + int(vTileCtrl)); } diff --git a/resources/shaders/gl3/d3d9/tile.vs.glsl b/resources/shaders/gl3/d3d9/tile.vs.glsl new file mode 100644 index 00000000..8257d318 --- /dev/null +++ b/resources/shaders/gl3/d3d9/tile.vs.glsl @@ -0,0 +1,123 @@ +#version {{version}} +// Automatically generated from files in pathfinder/shaders/. Do not edit! + + + + + + + + + + + + +#extension GL_GOOGLE_include_directive : enable + +precision highp float; + + + + + + + + + + + + + + + + +vec4 fetchUnscaled(sampler2D srcTexture, vec2 scale, vec2 originCoord, int entry){ + return texture(srcTexture,(originCoord + vec2(0.5)+ vec2(entry, 0))* scale); +} + +void computeTileVaryings(vec2 position, + int colorEntry, + sampler2D textureMetadata, + ivec2 textureMetadataSize, + out vec2 outColorTexCoord0, + out vec4 outBaseColor, + out vec4 outFilterParams0, + out vec4 outFilterParams1, + out vec4 outFilterParams2, + out int outCtrl){ + vec2 metadataScale = vec2(1.0)/ vec2(textureMetadataSize); + vec2 metadataEntryCoord = vec2(colorEntry % 128 * 8, colorEntry / 128); + vec4 colorTexMatrix0 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 0); + vec4 colorTexOffsets = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 1); + vec4 baseColor = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 2); + vec4 filterParams0 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 3); + vec4 filterParams1 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 4); + vec4 filterParams2 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 5); + vec4 extra = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 6); + outColorTexCoord0 = mat2(colorTexMatrix0)* position + colorTexOffsets . xy; + outBaseColor = baseColor; + outFilterParams0 = filterParams0; + outFilterParams1 = filterParams1; + outFilterParams2 = filterParams2; + outCtrl = int(extra . x); +} + + +uniform mat4 uTransform; +uniform vec2 uTileSize; +uniform sampler2D uTextureMetadata; +uniform ivec2 uTextureMetadataSize; +uniform sampler2D uZBuffer; +uniform ivec2 uZBufferSize; + +in ivec2 aTileOffset; +in ivec2 aTileOrigin; +in uvec4 aMaskTexCoord0; +in ivec2 aCtrlBackdrop; +in int aPathIndex; +in int aColor; + +out vec3 vMaskTexCoord0; +out vec2 vColorTexCoord0; +out vec4 vBaseColor; +out float vTileCtrl; +out vec4 vFilterParams0; +out vec4 vFilterParams1; +out vec4 vFilterParams2; +out float vCtrl; + +void main(){ + vec2 tileOrigin = vec2(aTileOrigin), tileOffset = vec2(aTileOffset); + vec2 position =(tileOrigin + tileOffset)* uTileSize; + + ivec4 zValue = ivec4(texture(uZBuffer,(tileOrigin + vec2(0.5))/ vec2(uZBufferSize))* 255.0); + if(aPathIndex <(zValue . x |(zValue . y << 8)|(zValue . z << 16)|(zValue . w << 24))){ + gl_Position = vec4(0.0); + return; + } + + uvec2 maskTileCoord = uvec2(aMaskTexCoord0 . x, aMaskTexCoord0 . y + 256u * aMaskTexCoord0 . z); + vec2 maskTexCoord0 =(vec2(maskTileCoord)+ tileOffset)* uTileSize; + if(aCtrlBackdrop . y == 0 && aMaskTexCoord0 . w != 0u){ + gl_Position = vec4(0.0); + return; + } + + int ctrl; + computeTileVaryings(position, + aColor, + uTextureMetadata, + uTextureMetadataSize, + vColorTexCoord0, + vBaseColor, + vFilterParams0, + vFilterParams1, + vFilterParams2, + ctrl); + + vTileCtrl = float(aCtrlBackdrop . x); + vCtrl = float(ctrl); + vMaskTexCoord0 = vec3(maskTexCoord0, float(aCtrlBackdrop . y)); + gl_Position = uTransform * vec4(position, 0.0, 1.0); +} + diff --git a/resources/shaders/gl3/d3d9/tile_clip_combine.fs.glsl b/resources/shaders/gl3/d3d9/tile_clip_combine.fs.glsl new file mode 100644 index 00000000..b097b871 --- /dev/null +++ b/resources/shaders/gl3/d3d9/tile_clip_combine.fs.glsl @@ -0,0 +1,34 @@ +#version {{version}} +// Automatically generated from files in pathfinder/shaders/. Do not edit! + + + + + + + + + + + + +precision highp float; + + + + + +uniform sampler2D uSrc; + +in vec2 vTexCoord0; +in float vBackdrop0; +in vec2 vTexCoord1; +in float vBackdrop1; + +out vec4 oFragColor; + +void main(){ + oFragColor = min(abs(texture(uSrc, vTexCoord0)+ vBackdrop0), + abs(texture(uSrc, vTexCoord1)+ vBackdrop1)); +} + diff --git a/resources/shaders/gl3/d3d9/tile_clip_combine.vs.glsl b/resources/shaders/gl3/d3d9/tile_clip_combine.vs.glsl new file mode 100644 index 00000000..38f85f04 --- /dev/null +++ b/resources/shaders/gl3/d3d9/tile_clip_combine.vs.glsl @@ -0,0 +1,54 @@ +#version {{version}} +// Automatically generated from files in pathfinder/shaders/. Do not edit! + + + + + + + + + + + + +precision highp float; + + + + + +uniform vec2 uFramebufferSize; + +in ivec2 aTileOffset; +in int aDestTileIndex; +in int aDestBackdrop; +in int aSrcTileIndex; +in int aSrcBackdrop; + +out vec2 vTexCoord0; +out float vBackdrop0; +out vec2 vTexCoord1; +out float vBackdrop1; + +void main(){ + vec2 destPosition = vec2(ivec2(aDestTileIndex % 256, aDestTileIndex / 256)+ aTileOffset); + vec2 srcPosition = vec2(ivec2(aSrcTileIndex % 256, aSrcTileIndex / 256)+ aTileOffset); + destPosition *= vec2(16.0, 4.0)/ uFramebufferSize; + srcPosition *= vec2(16.0, 4.0)/ uFramebufferSize; + + vTexCoord0 = destPosition; + vTexCoord1 = srcPosition; + + vBackdrop0 = float(aDestBackdrop); + vBackdrop1 = float(aSrcBackdrop); + + if(aDestTileIndex < 0) + destPosition = vec2(0.0); + + + + + gl_Position = vec4(mix(vec2(- 1.0), vec2(1.0), destPosition), 0.0, 1.0); +} + diff --git a/resources/shaders/gl4/tile_clip.fs.glsl b/resources/shaders/gl3/d3d9/tile_clip_copy.fs.glsl similarity index 69% rename from resources/shaders/gl4/tile_clip.fs.glsl rename to resources/shaders/gl3/d3d9/tile_clip_copy.fs.glsl index 9b8b6cd3..b1d846fe 100644 --- a/resources/shaders/gl4/tile_clip.fs.glsl +++ b/resources/shaders/gl3/d3d9/tile_clip_copy.fs.glsl @@ -21,11 +21,10 @@ precision highp float; uniform sampler2D uSrc; in vec2 vTexCoord; -in float vBackdrop; out vec4 oFragColor; void main(){ - oFragColor = clamp(abs(texture(uSrc, vTexCoord)+ vBackdrop), 0.0, 1.0); + oFragColor = texture(uSrc, vTexCoord); } diff --git a/resources/shaders/gl3/d3d9/tile_clip_copy.vs.glsl b/resources/shaders/gl3/d3d9/tile_clip_copy.vs.glsl new file mode 100644 index 00000000..04b2982f --- /dev/null +++ b/resources/shaders/gl3/d3d9/tile_clip_copy.vs.glsl @@ -0,0 +1,42 @@ +#version {{version}} +// Automatically generated from files in pathfinder/shaders/. Do not edit! + + + + + + + + + + + + +precision highp float; + + + + + +uniform vec2 uFramebufferSize; + +in ivec2 aTileOffset; +in int aTileIndex; + +out vec2 vTexCoord; + +void main(){ + vec2 position = vec2(ivec2(aTileIndex % 256, aTileIndex / 256)+ aTileOffset); + position *= vec2(16.0, 4.0)/ uFramebufferSize; + + vTexCoord = position; + + if(aTileIndex < 0) + position = vec2(0.0); + + + + + gl_Position = vec4(mix(vec2(- 1.0), vec2(1.0), position), 0.0, 1.0); +} + diff --git a/resources/shaders/gl3/tile_copy.fs.glsl b/resources/shaders/gl3/d3d9/tile_copy.fs.glsl similarity index 100% rename from resources/shaders/gl3/tile_copy.fs.glsl rename to resources/shaders/gl3/d3d9/tile_copy.fs.glsl diff --git a/resources/shaders/gl3/tile_copy.vs.glsl b/resources/shaders/gl3/d3d9/tile_copy.vs.glsl similarity index 100% rename from resources/shaders/gl3/tile_copy.vs.glsl rename to resources/shaders/gl3/d3d9/tile_copy.vs.glsl diff --git a/resources/shaders/gl3/fill.vs.glsl b/resources/shaders/gl3/fill.vs.glsl deleted file mode 100644 index 58b0b7f0..00000000 --- a/resources/shaders/gl3/fill.vs.glsl +++ /dev/null @@ -1,71 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - - - - - - - - - - - -precision highp float; - - - - - -uniform vec2 uFramebufferSize; -uniform vec2 uTileSize; - -in uvec2 aTessCoord; -in uint aFromPx; -in uint aToPx; -in vec2 aFromSubpx; -in vec2 aToSubpx; -in uint aTileIndex; - -out vec2 vFrom; -out vec2 vTo; - -vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth){ - uint tilesPerRow = uint(stencilTextureWidth / uTileSize . x); - uvec2 tileOffset = uvec2(tileIndex % tilesPerRow, tileIndex / tilesPerRow); - return vec2(tileOffset)* uTileSize * vec2(1.0, 0.25); -} - -void main(){ - vec2 tileOrigin = computeTileOffset(aTileIndex, uFramebufferSize . x); - - vec2 from = vec2(aFromPx & 15u, aFromPx >> 4u)+ aFromSubpx; - vec2 to = vec2(aToPx & 15u, aToPx >> 4u)+ aToSubpx; - - vec2 position; - if(aTessCoord . x == 0u) - position . x = floor(min(from . x, to . x)); - else - position . x = ceil(max(from . x, to . x)); - if(aTessCoord . y == 0u) - position . y = floor(min(from . y, to . y)); - else - position . y = uTileSize . y; - position . y = floor(position . y * 0.25); - - - - - - vec2 offset = vec2(0.0, 1.5)- position * vec2(1.0, 4.0); - vFrom = from + offset; - vTo = to + offset; - - vec2 globalPosition =(tileOrigin + position)/ uFramebufferSize * 2.0 - 1.0; - - - - gl_Position = vec4(globalPosition, 0.0, 1.0); -} - diff --git a/resources/shaders/gl3/tile.vs.glsl b/resources/shaders/gl3/tile.vs.glsl deleted file mode 100644 index 6f3819c0..00000000 --- a/resources/shaders/gl3/tile.vs.glsl +++ /dev/null @@ -1,59 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - - - - - - - - - - - -precision highp float; - - - - - -uniform mat4 uTransform; -uniform vec2 uTileSize; -uniform sampler2D uTextureMetadata; -uniform ivec2 uTextureMetadataSize; - -in ivec2 aTileOffset; -in ivec2 aTileOrigin; -in uvec2 aMaskTexCoord0; -in ivec2 aMaskBackdrop; -in int aColor; -in int aTileCtrl; - -out vec3 vMaskTexCoord0; -out vec2 vColorTexCoord0; -out vec4 vBaseColor; -out float vTileCtrl; - -void main(){ - vec2 tileOrigin = vec2(aTileOrigin), tileOffset = vec2(aTileOffset); - vec2 position =(tileOrigin + tileOffset)* uTileSize; - - vec2 maskTexCoord0 =(vec2(aMaskTexCoord0)+ tileOffset)* uTileSize; - - vec2 textureMetadataScale = vec2(1.0)/ vec2(uTextureMetadataSize); - vec2 metadataEntryCoord = vec2(aColor % 128 * 4, aColor / 128); - vec2 colorTexMatrix0Coord =(metadataEntryCoord + vec2(0.5, 0.5))* textureMetadataScale; - vec2 colorTexOffsetsCoord =(metadataEntryCoord + vec2(1.5, 0.5))* textureMetadataScale; - vec2 baseColorCoord =(metadataEntryCoord + vec2(2.5, 0.5))* textureMetadataScale; - vec4 colorTexMatrix0 = texture(uTextureMetadata, colorTexMatrix0Coord); - vec4 colorTexOffsets = texture(uTextureMetadata, colorTexOffsetsCoord); - vec4 baseColor = texture(uTextureMetadata, baseColorCoord); - - vColorTexCoord0 = mat2(colorTexMatrix0)* position + colorTexOffsets . xy; - vMaskTexCoord0 = vec3(maskTexCoord0, float(aMaskBackdrop . x)); - vBaseColor = baseColor; - vTileCtrl = float(aTileCtrl); - gl_Position = uTransform * vec4(position, 0.0, 1.0); -} - diff --git a/resources/shaders/gl3/tile_clip.vs.glsl b/resources/shaders/gl3/tile_clip.vs.glsl deleted file mode 100644 index 6693ec92..00000000 --- a/resources/shaders/gl3/tile_clip.vs.glsl +++ /dev/null @@ -1,36 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - - - - - - - - - - - -precision highp float; - - - - - -in ivec2 aTileOffset; -in ivec2 aDestTileOrigin; -in ivec2 aSrcTileOrigin; -in int aSrcBackdrop; - -out vec2 vTexCoord; -out float vBackdrop; - -void main(){ - vec2 destPosition = vec2(aDestTileOrigin + aTileOffset)/ vec2(256.0); - vec2 srcPosition = vec2(aSrcTileOrigin + aTileOffset)/ vec2(256.0); - vTexCoord = srcPosition; - vBackdrop = float(aSrcBackdrop); - gl_Position = vec4(mix(vec2(- 1.0), vec2(1.0), destPosition), 0.0, 1.0); -} - diff --git a/resources/shaders/gl4/fill.fs.glsl b/resources/shaders/gl4/d3d9/fill.fs.glsl similarity index 100% rename from resources/shaders/gl4/fill.fs.glsl rename to resources/shaders/gl4/d3d9/fill.fs.glsl diff --git a/resources/shaders/gl4/d3d9/fill.vs.glsl b/resources/shaders/gl4/d3d9/fill.vs.glsl new file mode 100644 index 00000000..b6e3ad45 --- /dev/null +++ b/resources/shaders/gl4/d3d9/fill.vs.glsl @@ -0,0 +1,86 @@ +#version {{version}} +// Automatically generated from files in pathfinder/shaders/. Do not edit! + + + + + + + + + + + + +#extension GL_GOOGLE_include_directive : enable + +precision highp float; + + + + + +uniform vec2 uFramebufferSize; +uniform vec2 uTileSize; + +in uvec2 aTessCoord; +in uvec4 aLineSegment; +in int aTileIndex; + +out vec2 vFrom; +out vec2 vTo; + +vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth, vec2 tileSize){ + uint tilesPerRow = uint(stencilTextureWidth / tileSize . x); + uvec2 tileOffset = uvec2(tileIndex % tilesPerRow, tileIndex / tilesPerRow); + return vec2(tileOffset)* tileSize * vec2(1.0, 0.25); +} + +vec4 computeVertexPosition(uint tileIndex, + uvec2 tessCoord, + uvec4 packedLineSegment, + vec2 tileSize, + vec2 framebufferSize, + out vec2 outFrom, + out vec2 outTo){ + vec2 tileOrigin = computeTileOffset(uint(tileIndex), framebufferSize . x, tileSize); + + vec4 lineSegment = vec4(packedLineSegment)/ 256.0; + vec2 from = lineSegment . xy, to = lineSegment . zw; + + vec2 position; + if(tessCoord . x == 0u) + position . x = floor(min(from . x, to . x)); + else + position . x = ceil(max(from . x, to . x)); + if(tessCoord . y == 0u) + position . y = floor(min(from . y, to . y)); + else + position . y = tileSize . y; + position . y = floor(position . y * 0.25); + + + + + + vec2 offset = vec2(0.0, 1.5)- position * vec2(1.0, 4.0); + outFrom = from + offset; + outTo = to + offset; + + vec2 globalPosition =(tileOrigin + position)/ framebufferSize * 2.0 - 1.0; + + + + return vec4(globalPosition, 0.0, 1.0); +} + +void main(){ + gl_Position = computeVertexPosition(uint(aTileIndex), + aTessCoord, + aLineSegment, + uTileSize, + uFramebufferSize, + vFrom, + vTo); +} + diff --git a/resources/shaders/gl3/tile.fs.glsl b/resources/shaders/gl4/d3d9/tile.fs.glsl similarity index 86% rename from resources/shaders/gl3/tile.fs.glsl rename to resources/shaders/gl4/d3d9/tile.fs.glsl index 33815bd9..ea281c03 100644 --- a/resources/shaders/gl3/tile.fs.glsl +++ b/resources/shaders/gl4/d3d9/tile.fs.glsl @@ -12,27 +12,6 @@ - - - - - - - - - - - - - - - - - - - - - #extension GL_GOOGLE_include_directive : enable precision highp float; @@ -83,24 +62,37 @@ precision highp float; -uniform sampler2D uColorTexture0; -uniform sampler2D uMaskTexture0; -uniform sampler2D uDestTexture; -uniform sampler2D uGammaLUT; -uniform vec2 uColorTextureSize0; -uniform vec2 uMaskTextureSize0; -uniform vec4 uFilterParams0; -uniform vec4 uFilterParams1; -uniform vec4 uFilterParams2; -uniform vec2 uFramebufferSize; -uniform int uCtrl; -in vec3 vMaskTexCoord0; -in vec2 vColorTexCoord0; -in vec4 vBaseColor; -in float vTileCtrl; -out vec4 oFragColor; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -567,27 +559,42 @@ float sampleMask(float maskAlpha, -void calculateColor(int tileCtrl, int ctrl){ +vec4 calculateColor(vec2 fragCoord, + sampler2D colorTexture0, + sampler2D maskTexture0, + sampler2D destTexture, + sampler2D gammaLUT, + vec2 colorTextureSize0, + vec2 maskTextureSize0, + vec4 filterParams0, + vec4 filterParams1, + vec4 filterParams2, + vec2 framebufferSize, + int ctrl, + vec3 maskTexCoord0, + vec2 colorTexCoord0, + vec4 baseColor, + int tileCtrl){ int maskCtrl0 =(tileCtrl >> 0)& 0x3; float maskAlpha = 1.0; - maskAlpha = sampleMask(maskAlpha, uMaskTexture0, uMaskTextureSize0, vMaskTexCoord0, maskCtrl0); + maskAlpha = sampleMask(maskAlpha, maskTexture0, maskTextureSize0, maskTexCoord0, maskCtrl0); - vec4 color = vBaseColor; + vec4 color = baseColor; int color0Combine =(ctrl >> 6)& 0x3; if(color0Combine != 0){ int color0Filter =(ctrl >> 4)& 0x3; - vec4 color0 = filterColor(vColorTexCoord0, - uColorTexture0, - uGammaLUT, - uColorTextureSize0, - gl_FragCoord . xy, - uFramebufferSize, - uFilterParams0, - uFilterParams1, - uFilterParams2, + vec4 color0 = filterColor(colorTexCoord0, + colorTexture0, + gammaLUT, + colorTextureSize0, + fragCoord, + framebufferSize, + filterParams0, + filterParams1, + filterParams2, color0Filter); color = combineColor0(color, color0, color0Combine); } @@ -597,18 +604,53 @@ void calculateColor(int tileCtrl, int ctrl){ int compositeOp =(ctrl >> 8)& 0xf; - color = composite(color, uDestTexture, uFramebufferSize, gl_FragCoord . xy, compositeOp); + color = composite(color, destTexture, framebufferSize, fragCoord, compositeOp); color . rgb *= color . a; - oFragColor = color; + return color; } +uniform sampler2D uColorTexture0; +uniform sampler2D uMaskTexture0; +uniform sampler2D uDestTexture; +uniform sampler2D uGammaLUT; +uniform vec2 uColorTextureSize0; +uniform vec2 uMaskTextureSize0; +uniform vec2 uFramebufferSize; + +in vec3 vMaskTexCoord0; +in vec2 vColorTexCoord0; +in vec4 vBaseColor; +in float vTileCtrl; +in vec4 vFilterParams0; +in vec4 vFilterParams1; +in vec4 vFilterParams2; +in float vCtrl; + +out vec4 oFragColor; + + void main(){ - calculateColor(int(vTileCtrl), uCtrl); + oFragColor = calculateColor(gl_FragCoord . xy, + uColorTexture0, + uMaskTexture0, + uDestTexture, + uGammaLUT, + uColorTextureSize0, + uMaskTextureSize0, + vFilterParams0, + vFilterParams1, + vFilterParams2, + uFramebufferSize, + int(vCtrl), + vMaskTexCoord0, + vColorTexCoord0, + vBaseColor, + int(vTileCtrl)); } diff --git a/resources/shaders/gl4/d3d9/tile.vs.glsl b/resources/shaders/gl4/d3d9/tile.vs.glsl new file mode 100644 index 00000000..8257d318 --- /dev/null +++ b/resources/shaders/gl4/d3d9/tile.vs.glsl @@ -0,0 +1,123 @@ +#version {{version}} +// Automatically generated from files in pathfinder/shaders/. Do not edit! + + + + + + + + + + + + +#extension GL_GOOGLE_include_directive : enable + +precision highp float; + + + + + + + + + + + + + + + + +vec4 fetchUnscaled(sampler2D srcTexture, vec2 scale, vec2 originCoord, int entry){ + return texture(srcTexture,(originCoord + vec2(0.5)+ vec2(entry, 0))* scale); +} + +void computeTileVaryings(vec2 position, + int colorEntry, + sampler2D textureMetadata, + ivec2 textureMetadataSize, + out vec2 outColorTexCoord0, + out vec4 outBaseColor, + out vec4 outFilterParams0, + out vec4 outFilterParams1, + out vec4 outFilterParams2, + out int outCtrl){ + vec2 metadataScale = vec2(1.0)/ vec2(textureMetadataSize); + vec2 metadataEntryCoord = vec2(colorEntry % 128 * 8, colorEntry / 128); + vec4 colorTexMatrix0 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 0); + vec4 colorTexOffsets = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 1); + vec4 baseColor = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 2); + vec4 filterParams0 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 3); + vec4 filterParams1 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 4); + vec4 filterParams2 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 5); + vec4 extra = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 6); + outColorTexCoord0 = mat2(colorTexMatrix0)* position + colorTexOffsets . xy; + outBaseColor = baseColor; + outFilterParams0 = filterParams0; + outFilterParams1 = filterParams1; + outFilterParams2 = filterParams2; + outCtrl = int(extra . x); +} + + +uniform mat4 uTransform; +uniform vec2 uTileSize; +uniform sampler2D uTextureMetadata; +uniform ivec2 uTextureMetadataSize; +uniform sampler2D uZBuffer; +uniform ivec2 uZBufferSize; + +in ivec2 aTileOffset; +in ivec2 aTileOrigin; +in uvec4 aMaskTexCoord0; +in ivec2 aCtrlBackdrop; +in int aPathIndex; +in int aColor; + +out vec3 vMaskTexCoord0; +out vec2 vColorTexCoord0; +out vec4 vBaseColor; +out float vTileCtrl; +out vec4 vFilterParams0; +out vec4 vFilterParams1; +out vec4 vFilterParams2; +out float vCtrl; + +void main(){ + vec2 tileOrigin = vec2(aTileOrigin), tileOffset = vec2(aTileOffset); + vec2 position =(tileOrigin + tileOffset)* uTileSize; + + ivec4 zValue = ivec4(texture(uZBuffer,(tileOrigin + vec2(0.5))/ vec2(uZBufferSize))* 255.0); + if(aPathIndex <(zValue . x |(zValue . y << 8)|(zValue . z << 16)|(zValue . w << 24))){ + gl_Position = vec4(0.0); + return; + } + + uvec2 maskTileCoord = uvec2(aMaskTexCoord0 . x, aMaskTexCoord0 . y + 256u * aMaskTexCoord0 . z); + vec2 maskTexCoord0 =(vec2(maskTileCoord)+ tileOffset)* uTileSize; + if(aCtrlBackdrop . y == 0 && aMaskTexCoord0 . w != 0u){ + gl_Position = vec4(0.0); + return; + } + + int ctrl; + computeTileVaryings(position, + aColor, + uTextureMetadata, + uTextureMetadataSize, + vColorTexCoord0, + vBaseColor, + vFilterParams0, + vFilterParams1, + vFilterParams2, + ctrl); + + vTileCtrl = float(aCtrlBackdrop . x); + vCtrl = float(ctrl); + vMaskTexCoord0 = vec3(maskTexCoord0, float(aCtrlBackdrop . y)); + gl_Position = uTransform * vec4(position, 0.0, 1.0); +} + diff --git a/resources/shaders/gl4/d3d9/tile_clip_combine.fs.glsl b/resources/shaders/gl4/d3d9/tile_clip_combine.fs.glsl new file mode 100644 index 00000000..b097b871 --- /dev/null +++ b/resources/shaders/gl4/d3d9/tile_clip_combine.fs.glsl @@ -0,0 +1,34 @@ +#version {{version}} +// Automatically generated from files in pathfinder/shaders/. Do not edit! + + + + + + + + + + + + +precision highp float; + + + + + +uniform sampler2D uSrc; + +in vec2 vTexCoord0; +in float vBackdrop0; +in vec2 vTexCoord1; +in float vBackdrop1; + +out vec4 oFragColor; + +void main(){ + oFragColor = min(abs(texture(uSrc, vTexCoord0)+ vBackdrop0), + abs(texture(uSrc, vTexCoord1)+ vBackdrop1)); +} + diff --git a/resources/shaders/gl4/d3d9/tile_clip_combine.vs.glsl b/resources/shaders/gl4/d3d9/tile_clip_combine.vs.glsl new file mode 100644 index 00000000..38f85f04 --- /dev/null +++ b/resources/shaders/gl4/d3d9/tile_clip_combine.vs.glsl @@ -0,0 +1,54 @@ +#version {{version}} +// Automatically generated from files in pathfinder/shaders/. Do not edit! + + + + + + + + + + + + +precision highp float; + + + + + +uniform vec2 uFramebufferSize; + +in ivec2 aTileOffset; +in int aDestTileIndex; +in int aDestBackdrop; +in int aSrcTileIndex; +in int aSrcBackdrop; + +out vec2 vTexCoord0; +out float vBackdrop0; +out vec2 vTexCoord1; +out float vBackdrop1; + +void main(){ + vec2 destPosition = vec2(ivec2(aDestTileIndex % 256, aDestTileIndex / 256)+ aTileOffset); + vec2 srcPosition = vec2(ivec2(aSrcTileIndex % 256, aSrcTileIndex / 256)+ aTileOffset); + destPosition *= vec2(16.0, 4.0)/ uFramebufferSize; + srcPosition *= vec2(16.0, 4.0)/ uFramebufferSize; + + vTexCoord0 = destPosition; + vTexCoord1 = srcPosition; + + vBackdrop0 = float(aDestBackdrop); + vBackdrop1 = float(aSrcBackdrop); + + if(aDestTileIndex < 0) + destPosition = vec2(0.0); + + + + + gl_Position = vec4(mix(vec2(- 1.0), vec2(1.0), destPosition), 0.0, 1.0); +} + diff --git a/resources/shaders/gl3/tile_clip.fs.glsl b/resources/shaders/gl4/d3d9/tile_clip_copy.fs.glsl similarity index 69% rename from resources/shaders/gl3/tile_clip.fs.glsl rename to resources/shaders/gl4/d3d9/tile_clip_copy.fs.glsl index 9b8b6cd3..b1d846fe 100644 --- a/resources/shaders/gl3/tile_clip.fs.glsl +++ b/resources/shaders/gl4/d3d9/tile_clip_copy.fs.glsl @@ -21,11 +21,10 @@ precision highp float; uniform sampler2D uSrc; in vec2 vTexCoord; -in float vBackdrop; out vec4 oFragColor; void main(){ - oFragColor = clamp(abs(texture(uSrc, vTexCoord)+ vBackdrop), 0.0, 1.0); + oFragColor = texture(uSrc, vTexCoord); } diff --git a/resources/shaders/gl4/d3d9/tile_clip_copy.vs.glsl b/resources/shaders/gl4/d3d9/tile_clip_copy.vs.glsl new file mode 100644 index 00000000..04b2982f --- /dev/null +++ b/resources/shaders/gl4/d3d9/tile_clip_copy.vs.glsl @@ -0,0 +1,42 @@ +#version {{version}} +// Automatically generated from files in pathfinder/shaders/. Do not edit! + + + + + + + + + + + + +precision highp float; + + + + + +uniform vec2 uFramebufferSize; + +in ivec2 aTileOffset; +in int aTileIndex; + +out vec2 vTexCoord; + +void main(){ + vec2 position = vec2(ivec2(aTileIndex % 256, aTileIndex / 256)+ aTileOffset); + position *= vec2(16.0, 4.0)/ uFramebufferSize; + + vTexCoord = position; + + if(aTileIndex < 0) + position = vec2(0.0); + + + + + gl_Position = vec4(mix(vec2(- 1.0), vec2(1.0), position), 0.0, 1.0); +} + diff --git a/resources/shaders/gl4/tile_copy.fs.glsl b/resources/shaders/gl4/d3d9/tile_copy.fs.glsl similarity index 100% rename from resources/shaders/gl4/tile_copy.fs.glsl rename to resources/shaders/gl4/d3d9/tile_copy.fs.glsl diff --git a/resources/shaders/gl4/tile_copy.vs.glsl b/resources/shaders/gl4/d3d9/tile_copy.vs.glsl similarity index 100% rename from resources/shaders/gl4/tile_copy.vs.glsl rename to resources/shaders/gl4/d3d9/tile_copy.vs.glsl diff --git a/resources/shaders/gl4/fill.vs.glsl b/resources/shaders/gl4/fill.vs.glsl deleted file mode 100644 index 58b0b7f0..00000000 --- a/resources/shaders/gl4/fill.vs.glsl +++ /dev/null @@ -1,71 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - - - - - - - - - - - -precision highp float; - - - - - -uniform vec2 uFramebufferSize; -uniform vec2 uTileSize; - -in uvec2 aTessCoord; -in uint aFromPx; -in uint aToPx; -in vec2 aFromSubpx; -in vec2 aToSubpx; -in uint aTileIndex; - -out vec2 vFrom; -out vec2 vTo; - -vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth){ - uint tilesPerRow = uint(stencilTextureWidth / uTileSize . x); - uvec2 tileOffset = uvec2(tileIndex % tilesPerRow, tileIndex / tilesPerRow); - return vec2(tileOffset)* uTileSize * vec2(1.0, 0.25); -} - -void main(){ - vec2 tileOrigin = computeTileOffset(aTileIndex, uFramebufferSize . x); - - vec2 from = vec2(aFromPx & 15u, aFromPx >> 4u)+ aFromSubpx; - vec2 to = vec2(aToPx & 15u, aToPx >> 4u)+ aToSubpx; - - vec2 position; - if(aTessCoord . x == 0u) - position . x = floor(min(from . x, to . x)); - else - position . x = ceil(max(from . x, to . x)); - if(aTessCoord . y == 0u) - position . y = floor(min(from . y, to . y)); - else - position . y = uTileSize . y; - position . y = floor(position . y * 0.25); - - - - - - vec2 offset = vec2(0.0, 1.5)- position * vec2(1.0, 4.0); - vFrom = from + offset; - vTo = to + offset; - - vec2 globalPosition =(tileOrigin + position)/ uFramebufferSize * 2.0 - 1.0; - - - - gl_Position = vec4(globalPosition, 0.0, 1.0); -} - diff --git a/resources/shaders/gl4/tile.vs.glsl b/resources/shaders/gl4/tile.vs.glsl deleted file mode 100644 index 6f3819c0..00000000 --- a/resources/shaders/gl4/tile.vs.glsl +++ /dev/null @@ -1,59 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - - - - - - - - - - - -precision highp float; - - - - - -uniform mat4 uTransform; -uniform vec2 uTileSize; -uniform sampler2D uTextureMetadata; -uniform ivec2 uTextureMetadataSize; - -in ivec2 aTileOffset; -in ivec2 aTileOrigin; -in uvec2 aMaskTexCoord0; -in ivec2 aMaskBackdrop; -in int aColor; -in int aTileCtrl; - -out vec3 vMaskTexCoord0; -out vec2 vColorTexCoord0; -out vec4 vBaseColor; -out float vTileCtrl; - -void main(){ - vec2 tileOrigin = vec2(aTileOrigin), tileOffset = vec2(aTileOffset); - vec2 position =(tileOrigin + tileOffset)* uTileSize; - - vec2 maskTexCoord0 =(vec2(aMaskTexCoord0)+ tileOffset)* uTileSize; - - vec2 textureMetadataScale = vec2(1.0)/ vec2(uTextureMetadataSize); - vec2 metadataEntryCoord = vec2(aColor % 128 * 4, aColor / 128); - vec2 colorTexMatrix0Coord =(metadataEntryCoord + vec2(0.5, 0.5))* textureMetadataScale; - vec2 colorTexOffsetsCoord =(metadataEntryCoord + vec2(1.5, 0.5))* textureMetadataScale; - vec2 baseColorCoord =(metadataEntryCoord + vec2(2.5, 0.5))* textureMetadataScale; - vec4 colorTexMatrix0 = texture(uTextureMetadata, colorTexMatrix0Coord); - vec4 colorTexOffsets = texture(uTextureMetadata, colorTexOffsetsCoord); - vec4 baseColor = texture(uTextureMetadata, baseColorCoord); - - vColorTexCoord0 = mat2(colorTexMatrix0)* position + colorTexOffsets . xy; - vMaskTexCoord0 = vec3(maskTexCoord0, float(aMaskBackdrop . x)); - vBaseColor = baseColor; - vTileCtrl = float(aTileCtrl); - gl_Position = uTransform * vec4(position, 0.0, 1.0); -} - diff --git a/resources/shaders/gl4/tile_clip.vs.glsl b/resources/shaders/gl4/tile_clip.vs.glsl deleted file mode 100644 index 6693ec92..00000000 --- a/resources/shaders/gl4/tile_clip.vs.glsl +++ /dev/null @@ -1,36 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - - - - - - - - - - - -precision highp float; - - - - - -in ivec2 aTileOffset; -in ivec2 aDestTileOrigin; -in ivec2 aSrcTileOrigin; -in int aSrcBackdrop; - -out vec2 vTexCoord; -out float vBackdrop; - -void main(){ - vec2 destPosition = vec2(aDestTileOrigin + aTileOffset)/ vec2(256.0); - vec2 srcPosition = vec2(aSrcTileOrigin + aTileOffset)/ vec2(256.0); - vTexCoord = srcPosition; - vBackdrop = float(aSrcBackdrop); - gl_Position = vec4(mix(vec2(- 1.0), vec2(1.0), destPosition), 0.0, 1.0); -} - diff --git a/resources/shaders/gl4/tile_fill.fs.glsl b/resources/shaders/gl4/tile_fill.fs.glsl deleted file mode 100644 index 88b566ff..00000000 --- a/resources/shaders/gl4/tile_fill.fs.glsl +++ /dev/null @@ -1,708 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - - - - - - - - - - - -#extension GL_GOOGLE_include_directive : enable - -precision highp float; -precision highp sampler2D; - -uniform sampler2D uColorTexture0; -uniform sampler2D uMaskTexture0; -uniform sampler2D uDestTexture; -uniform sampler2D uGammaLUT; -uniform vec4 uFilterParams0; -uniform vec4 uFilterParams1; -uniform vec4 uFilterParams2; -uniform vec2 uFramebufferSize; -uniform vec2 uColorTextureSize0; -uniform int uCtrl; -uniform sampler2D uAreaLUT; - -layout(std430, binding = 0)buffer bFills { - restrict readonly uvec2 iFills[]; -}; - -layout(std430, binding = 1)buffer bNextFills { - restrict readonly int iNextFills[]; -}; - -layout(std430, binding = 2)buffer bFillTileMap { - restrict readonly int iFillTileMap[]; -}; - -in vec2 vTileSubCoord; -flat in uint vMaskTileIndex0; -flat in int vMaskTileBackdrop0; -in vec2 vColorTexCoord0; -in vec4 vBaseColor; -in float vTileCtrl; - -out vec4 oFragColor; - - - - - - - - - - - - -vec4 computeCoverage(vec2 from, vec2 to, sampler2D areaLUT){ - - vec2 left = from . x < to . x ? from : to, right = from . x < to . x ? to : from; - - - vec2 window = clamp(vec2(from . x, to . x), - 0.5, 0.5); - float offset = mix(window . x, window . y, 0.5)- left . x; - float t = offset /(right . x - left . x); - - - float y = mix(left . y, right . y, t); - float d =(right . y - left . y)/(right . x - left . x); - - - float dX = window . x - window . y; - return texture(areaLUT, vec2(y + 8.0, abs(d * dX))/ 16.0)* dX; -} - - - - - - - - - - - - -vec4 computeCoverage(vec2 from, vec2 to, sampler2D areaLUT); - -ivec2 calculateTileOrigin(uint tileIndex){ - return ivec2(tileIndex & 0xff,(tileIndex >> 8u)& 0xff)* 16; -} - -vec4 calculateFillAlpha(ivec2 tileSubCoord, uint tileIndex){ - int fillIndex = iFillTileMap[tileIndex]; - if(fillIndex < 0) - return vec4(0.0); - - vec4 coverages = vec4(0.0); - do { - uvec2 fill = iFills[fillIndex]; - vec2 from = vec2(fill . y & 0xf,(fill . y >> 4u)& 0xf)+ - vec2(fill . x & 0xff,(fill . x >> 8u)& 0xff)/ 256.0; - vec2 to = vec2((fill . y >> 8u)& 0xf,(fill . y >> 12u)& 0xf)+ - vec2((fill . x >> 16u)& 0xff,(fill . x >> 24u)& 0xff)/ 256.0; - - coverages += computeCoverage(from -(vec2(tileSubCoord)+ vec2(0.5)), - to -(vec2(tileSubCoord)+ vec2(0.5)), - uAreaLUT); - - fillIndex = iNextFills[fillIndex]; - } while(fillIndex >= 0); - - return coverages; -} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -vec4 sampleColor(sampler2D colorTexture, vec2 colorTexCoord){ - return texture(colorTexture, colorTexCoord); -} - - - -vec4 combineColor0(vec4 destColor, vec4 srcColor, int op){ - switch(op){ - case 0x1 : - return vec4(srcColor . rgb, srcColor . a * destColor . a); - case 0x2 : - return vec4(destColor . rgb, srcColor . a * destColor . a); - } - return destColor; -} - - - -float filterTextSample1Tap(float offset, sampler2D colorTexture, vec2 colorTexCoord){ - return texture(colorTexture, colorTexCoord + vec2(offset, 0.0)). r; -} - - -void filterTextSample9Tap(out vec4 outAlphaLeft, - out float outAlphaCenter, - out vec4 outAlphaRight, - sampler2D colorTexture, - vec2 colorTexCoord, - vec4 kernel, - float onePixel){ - bool wide = kernel . x > 0.0; - outAlphaLeft = - vec4(wide ? filterTextSample1Tap(- 4.0 * onePixel, colorTexture, colorTexCoord): 0.0, - filterTextSample1Tap(- 3.0 * onePixel, colorTexture, colorTexCoord), - filterTextSample1Tap(- 2.0 * onePixel, colorTexture, colorTexCoord), - filterTextSample1Tap(- 1.0 * onePixel, colorTexture, colorTexCoord)); - outAlphaCenter = filterTextSample1Tap(0.0, colorTexture, colorTexCoord); - outAlphaRight = - vec4(filterTextSample1Tap(1.0 * onePixel, colorTexture, colorTexCoord), - filterTextSample1Tap(2.0 * onePixel, colorTexture, colorTexCoord), - filterTextSample1Tap(3.0 * onePixel, colorTexture, colorTexCoord), - wide ? filterTextSample1Tap(4.0 * onePixel, colorTexture, colorTexCoord): 0.0); -} - -float filterTextConvolve7Tap(vec4 alpha0, vec3 alpha1, vec4 kernel){ - return dot(alpha0, kernel)+ dot(alpha1, kernel . zyx); -} - -float filterTextGammaCorrectChannel(float bgColor, float fgColor, sampler2D gammaLUT){ - return texture(gammaLUT, vec2(fgColor, 1.0 - bgColor)). r; -} - - -vec3 filterTextGammaCorrect(vec3 bgColor, vec3 fgColor, sampler2D gammaLUT){ - return vec3(filterTextGammaCorrectChannel(bgColor . r, fgColor . r, gammaLUT), - filterTextGammaCorrectChannel(bgColor . g, fgColor . g, gammaLUT), - filterTextGammaCorrectChannel(bgColor . b, fgColor . b, gammaLUT)); -} - - - - - - -vec4 filterText(vec2 colorTexCoord, - sampler2D colorTexture, - sampler2D gammaLUT, - vec2 colorTextureSize, - vec4 filterParams0, - vec4 filterParams1, - vec4 filterParams2){ - - vec4 kernel = filterParams0; - vec3 bgColor = filterParams1 . rgb; - vec3 fgColor = filterParams2 . rgb; - bool gammaCorrectionEnabled = filterParams2 . a != 0.0; - - - vec3 alpha; - if(kernel . w == 0.0){ - alpha = texture(colorTexture, colorTexCoord). rrr; - } else { - vec4 alphaLeft, alphaRight; - float alphaCenter; - filterTextSample9Tap(alphaLeft, - alphaCenter, - alphaRight, - colorTexture, - colorTexCoord, - kernel, - 1.0 / colorTextureSize . x); - - float r = filterTextConvolve7Tap(alphaLeft, vec3(alphaCenter, alphaRight . xy), kernel); - float g = filterTextConvolve7Tap(vec4(alphaLeft . yzw, alphaCenter), alphaRight . xyz, kernel); - float b = filterTextConvolve7Tap(vec4(alphaLeft . zw, alphaCenter, alphaRight . x), - alphaRight . yzw, - kernel); - - alpha = vec3(r, g, b); - } - - - if(gammaCorrectionEnabled) - alpha = filterTextGammaCorrect(bgColor, alpha, gammaLUT); - - - return vec4(mix(bgColor, fgColor, alpha), 1.0); -} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -vec4 filterRadialGradient(vec2 colorTexCoord, - sampler2D colorTexture, - vec2 colorTextureSize, - vec2 fragCoord, - vec2 framebufferSize, - vec4 filterParams0, - vec4 filterParams1){ - vec2 lineFrom = filterParams0 . xy, lineVector = filterParams0 . zw; - vec2 radii = filterParams1 . xy, uvOrigin = filterParams1 . zw; - - vec2 dP = colorTexCoord - lineFrom, dC = lineVector; - float dR = radii . y - radii . x; - - float a = dot(dC, dC)- dR * dR; - float b = dot(dP, dC)+ radii . x * dR; - float c = dot(dP, dP)- radii . x * radii . x; - float discrim = b * b - a * c; - - vec4 color = vec4(0.0); - if(abs(discrim)>= 0.00001){ - vec2 ts = vec2(sqrt(discrim)* vec2(1.0, - 1.0)+ vec2(b))/ vec2(a); - if(ts . x > ts . y) - ts = ts . yx; - float t = ts . x >= 0.0 ? ts . x : ts . y; - color = texture(colorTexture, uvOrigin + vec2(clamp(t, 0.0, 1.0), 0.0)); - } - - return color; -} - - - - - - -vec4 filterBlur(vec2 colorTexCoord, - sampler2D colorTexture, - vec2 colorTextureSize, - vec4 filterParams0, - vec4 filterParams1){ - - vec2 srcOffsetScale = filterParams0 . xy / colorTextureSize; - int support = int(filterParams0 . z); - vec3 gaussCoeff = filterParams1 . xyz; - - - float gaussSum = gaussCoeff . x; - vec4 color = texture(colorTexture, colorTexCoord)* gaussCoeff . x; - gaussCoeff . xy *= gaussCoeff . yz; - - - - - - - - - - for(int i = 1;i <= support;i += 2){ - float gaussPartialSum = gaussCoeff . x; - gaussCoeff . xy *= gaussCoeff . yz; - gaussPartialSum += gaussCoeff . x; - - vec2 srcOffset = srcOffsetScale *(float(i)+ gaussCoeff . x / gaussPartialSum); - color +=(texture(colorTexture, colorTexCoord - srcOffset)+ - texture(colorTexture, colorTexCoord + srcOffset))* gaussPartialSum; - - gaussSum += 2.0 * gaussPartialSum; - gaussCoeff . xy *= gaussCoeff . yz; - } - - - return color / gaussSum; -} - -vec4 filterNone(vec2 colorTexCoord, sampler2D colorTexture){ - return sampleColor(colorTexture, colorTexCoord); -} - -vec4 filterColor(vec2 colorTexCoord, - sampler2D colorTexture, - sampler2D gammaLUT, - vec2 colorTextureSize, - vec2 fragCoord, - vec2 framebufferSize, - vec4 filterParams0, - vec4 filterParams1, - vec4 filterParams2, - int colorFilter){ - switch(colorFilter){ - case 0x1 : - return filterRadialGradient(colorTexCoord, - colorTexture, - colorTextureSize, - fragCoord, - framebufferSize, - filterParams0, - filterParams1); - case 0x3 : - return filterBlur(colorTexCoord, - colorTexture, - colorTextureSize, - filterParams0, - filterParams1); - case 0x2 : - return filterText(colorTexCoord, - colorTexture, - gammaLUT, - colorTextureSize, - filterParams0, - filterParams1, - filterParams2); - } - return filterNone(colorTexCoord, colorTexture); -} - - - -vec3 compositeSelect(bvec3 cond, vec3 ifTrue, vec3 ifFalse){ - return vec3(cond . x ? ifTrue . x : ifFalse . x, - cond . y ? ifTrue . y : ifFalse . y, - cond . z ? ifTrue . z : ifFalse . z); -} - -float compositeDivide(float num, float denom){ - return denom != 0.0 ? num / denom : 0.0; -} - -vec3 compositeColorDodge(vec3 destColor, vec3 srcColor){ - bvec3 destZero = equal(destColor, vec3(0.0)), srcOne = equal(srcColor, vec3(1.0)); - return compositeSelect(destZero, - vec3(0.0), - compositeSelect(srcOne, vec3(1.0), destColor /(vec3(1.0)- srcColor))); -} - - -vec3 compositeHSLToRGB(vec3 hsl){ - float a = hsl . y * min(hsl . z, 1.0 - hsl . z); - vec3 ks = mod(vec3(0.0, 8.0, 4.0)+ vec3(hsl . x * 1.9098593171027443), 12.0); - return hsl . zzz - clamp(min(ks - vec3(3.0), vec3(9.0)- ks), - 1.0, 1.0)* a; -} - - -vec3 compositeRGBToHSL(vec3 rgb){ - float v = max(max(rgb . r, rgb . g), rgb . b), xMin = min(min(rgb . r, rgb . g), rgb . b); - float c = v - xMin, l = mix(xMin, v, 0.5); - vec3 terms = rgb . r == v ? vec3(0.0, rgb . gb): - rgb . g == v ? vec3(2.0, rgb . br): - vec3(4.0, rgb . rg); - float h = 1.0471975511965976 * compositeDivide(terms . x * c + terms . y - terms . z, c); - float s = compositeDivide(c, v); - return vec3(h, s, l); -} - -vec3 compositeScreen(vec3 destColor, vec3 srcColor){ - return destColor + srcColor - destColor * srcColor; -} - -vec3 compositeHardLight(vec3 destColor, vec3 srcColor){ - return compositeSelect(lessThanEqual(srcColor, vec3(0.5)), - destColor * vec3(2.0)* srcColor, - compositeScreen(destColor, vec3(2.0)* srcColor - vec3(1.0))); -} - -vec3 compositeSoftLight(vec3 destColor, vec3 srcColor){ - vec3 darkenedDestColor = - compositeSelect(lessThanEqual(destColor, vec3(0.25)), - ((vec3(16.0)* destColor - 12.0)* destColor + 4.0)* destColor, - sqrt(destColor)); - vec3 factor = compositeSelect(lessThanEqual(srcColor, vec3(0.5)), - destColor *(vec3(1.0)- destColor), - darkenedDestColor - destColor); - return destColor +(srcColor * 2.0 - 1.0)* factor; -} - -vec3 compositeHSL(vec3 destColor, vec3 srcColor, int op){ - switch(op){ - case 0xc : - return vec3(srcColor . x, destColor . y, destColor . z); - case 0xd : - return vec3(destColor . x, srcColor . y, destColor . z); - case 0xe : - return vec3(srcColor . x, srcColor . y, destColor . z); - default : - return vec3(destColor . x, destColor . y, srcColor . z); - } -} - -vec3 compositeRGB(vec3 destColor, vec3 srcColor, int op){ - switch(op){ - case 0x1 : - return destColor * srcColor; - case 0x2 : - return compositeScreen(destColor, srcColor); - case 0x3 : - return compositeHardLight(srcColor, destColor); - case 0x4 : - return min(destColor, srcColor); - case 0x5 : - return max(destColor, srcColor); - case 0x6 : - return compositeColorDodge(destColor, srcColor); - case 0x7 : - return vec3(1.0)- compositeColorDodge(vec3(1.0)- destColor, vec3(1.0)- srcColor); - case 0x8 : - return compositeHardLight(destColor, srcColor); - case 0x9 : - return compositeSoftLight(destColor, srcColor); - case 0xa : - return abs(destColor - srcColor); - case 0xb : - return destColor + srcColor - vec3(2.0)* destColor * srcColor; - case 0xc : - case 0xd : - case 0xe : - case 0xf : - return compositeHSLToRGB(compositeHSL(compositeRGBToHSL(destColor), - compositeRGBToHSL(srcColor), - op)); - } - return srcColor; -} - -vec4 composite(vec4 srcColor, - sampler2D destTexture, - vec2 destTextureSize, - vec2 fragCoord, - int op){ - if(op == 0x0) - return srcColor; - - - vec2 destTexCoord = fragCoord / destTextureSize; - vec4 destColor = texture(destTexture, destTexCoord); - vec3 blendedRGB = compositeRGB(destColor . rgb, srcColor . rgb, op); - return vec4(srcColor . a *(1.0 - destColor . a)* srcColor . rgb + - srcColor . a * destColor . a * blendedRGB + - (1.0 - srcColor . a)* destColor . rgb, - 1.0); -} - - - -float sampleMask(float maskAlpha, - sampler2D maskTexture, - vec2 maskTextureSize, - vec3 maskTexCoord, - int maskCtrl){ - if(maskCtrl == 0) - return maskAlpha; - - ivec2 maskTexCoordI = ivec2(floor(maskTexCoord . xy)); - vec4 texel = texture(maskTexture,(vec2(maskTexCoordI / ivec2(1, 4))+ 0.5)/ maskTextureSize); - float coverage = texel[maskTexCoordI . y % 4]+ maskTexCoord . z; - - if((maskCtrl & 0x1)!= 0) - coverage = abs(coverage); - else - coverage = 1.0 - abs(1.0 - mod(coverage, 2.0)); - return min(maskAlpha, coverage); -} - - - -vec4 calculateColorWithMaskAlpha(float maskAlpha, - vec4 baseColor, - vec2 colorTexCoord0, - vec2 fragCoord, - int ctrl){ - - vec4 color = baseColor; - int color0Combine =(ctrl >> 6)& - 0x3; - if(color0Combine != 0){ - int color0Filter =(ctrl >> 4)& 0x3; - vec4 color0 = filterColor(colorTexCoord0, - uColorTexture0, - uGammaLUT, - uColorTextureSize0, - fragCoord, - uFramebufferSize, - uFilterParams0, - uFilterParams1, - uFilterParams2, - color0Filter); - color = combineColor0(color, color0, color0Combine); - } - - - color . a *= maskAlpha; - - - - - - - - - - color . rgb *= color . a; - return color; -} - - -vec4 calculateColor(int tileCtrl, int ctrl){ - float maskAlpha = 1.0; - int maskCtrl0 =(ctrl >> 0)& 0x1; - int maskTileCtrl0 =(tileCtrl >> 0)& 0x3; - uint maskTileIndex0 = vMaskTileIndex0; - if(maskCtrl0 != 0 && maskTileCtrl0 != 0){ - ivec2 tileSubCoord = ivec2(floor(vTileSubCoord)); - vec4 alphas = calculateFillAlpha(tileSubCoord, maskTileIndex0)+ float(vMaskTileBackdrop0); - maskAlpha = alphas . x; - } - return calculateColorWithMaskAlpha(maskAlpha, - vBaseColor, - vColorTexCoord0, - gl_FragCoord . xy, - ctrl); -} - - - - - -void main(){ - oFragColor = calculateColor(int(vTileCtrl), uCtrl); - -} - diff --git a/resources/shaders/gl4/tile_fill.vs.glsl b/resources/shaders/gl4/tile_fill.vs.glsl deleted file mode 100644 index 1c089c09..00000000 --- a/resources/shaders/gl4/tile_fill.vs.glsl +++ /dev/null @@ -1,58 +0,0 @@ -#version {{version}} -// Automatically generated from files in pathfinder/shaders/. Do not edit! - - - - - - - - - - - - -precision highp float; -precision highp sampler2D; - -uniform mat4 uTransform; -uniform vec2 uTileSize; -uniform sampler2D uTextureMetadata; -uniform ivec2 uTextureMetadataSize; - -in ivec2 aTileOffset; -in ivec2 aTileOrigin; -in uint aMaskTileIndex0; -in ivec2 aMaskBackdrop; -in int aColor; -in int aTileCtrl; - -out vec2 vTileSubCoord; -flat out uint vMaskTileIndex0; -flat out int vMaskTileBackdrop0; -out vec2 vColorTexCoord0; -out vec4 vBaseColor; -out float vTileCtrl; - -void main(){ - vec2 tileOrigin = vec2(aTileOrigin), tileOffset = vec2(aTileOffset); - vec2 position =(tileOrigin + tileOffset)* uTileSize; - - vec2 textureMetadataScale = vec2(1.0)/ vec2(uTextureMetadataSize); - vec2 metadataEntryCoord = vec2(aColor % 128 * 4, aColor / 128); - vec2 colorTexMatrix0Coord =(metadataEntryCoord + vec2(0.5, 0.5))* textureMetadataScale; - vec2 colorTexOffsetsCoord =(metadataEntryCoord + vec2(1.5, 0.5))* textureMetadataScale; - vec2 baseColorCoord =(metadataEntryCoord + vec2(2.5, 0.5))* textureMetadataScale; - vec4 colorTexMatrix0 = texture(uTextureMetadata, colorTexMatrix0Coord); - vec4 colorTexOffsets = texture(uTextureMetadata, colorTexOffsetsCoord); - vec4 baseColor = texture(uTextureMetadata, baseColorCoord); - - vTileSubCoord = tileOffset * vec2(16.0); - vColorTexCoord0 = mat2(colorTexMatrix0)* position + colorTexOffsets . xy; - vMaskTileIndex0 = aMaskTileIndex0; - vMaskTileBackdrop0 = aMaskBackdrop . x; - vBaseColor = baseColor; - vTileCtrl = float(aTileCtrl); - gl_Position = uTransform * vec4(position, 0.0, 1.0); -} - diff --git a/resources/shaders/metal/fill.fs.metal b/resources/shaders/metal/d3d9/fill.fs.metal similarity index 100% rename from resources/shaders/metal/fill.fs.metal rename to resources/shaders/metal/d3d9/fill.fs.metal diff --git a/resources/shaders/metal/d3d9/fill.vs.metal b/resources/shaders/metal/d3d9/fill.vs.metal new file mode 100644 index 00000000..9cc7459d --- /dev/null +++ b/resources/shaders/metal/d3d9/fill.vs.metal @@ -0,0 +1,83 @@ +// Automatically generated from files in pathfinder/shaders/. Do not edit! +#pragma clang diagnostic ignored "-Wmissing-prototypes" + +#include +#include + +using namespace metal; + +struct main0_out +{ + float2 vFrom [[user(locn0)]]; + float2 vTo [[user(locn1)]]; + float4 gl_Position [[position]]; +}; + +struct main0_in +{ + uint2 aTessCoord [[attribute(0)]]; + uint4 aLineSegment [[attribute(1)]]; + int aTileIndex [[attribute(2)]]; +}; + +static inline __attribute__((always_inline)) +float2 computeTileOffset(thread const uint& tileIndex, thread const float& stencilTextureWidth, thread const float2& tileSize) +{ + uint tilesPerRow = uint(stencilTextureWidth / tileSize.x); + uint2 tileOffset = uint2(tileIndex % tilesPerRow, tileIndex / tilesPerRow); + return (float2(tileOffset) * tileSize) * float2(1.0, 0.25); +} + +static inline __attribute__((always_inline)) +float4 computeVertexPosition(thread const uint& tileIndex, thread const uint2& tessCoord, thread const uint4& packedLineSegment, thread const float2& tileSize, thread const float2& framebufferSize, thread float2& outFrom, thread float2& outTo) +{ + uint param = tileIndex; + float param_1 = framebufferSize.x; + float2 param_2 = tileSize; + float2 tileOrigin = computeTileOffset(param, param_1, param_2); + float4 lineSegment = float4(packedLineSegment) / float4(256.0); + float2 from = lineSegment.xy; + float2 to = lineSegment.zw; + float2 position; + if (tessCoord.x == 0u) + { + position.x = floor(fast::min(from.x, to.x)); + } + else + { + position.x = ceil(fast::max(from.x, to.x)); + } + if (tessCoord.y == 0u) + { + position.y = floor(fast::min(from.y, to.y)); + } + else + { + position.y = tileSize.y; + } + position.y = floor(position.y * 0.25); + float2 offset = float2(0.0, 1.5) - (position * float2(1.0, 4.0)); + outFrom = from + offset; + outTo = to + offset; + float2 globalPosition = (((tileOrigin + position) / framebufferSize) * 2.0) - float2(1.0); + globalPosition.y = -globalPosition.y; + return float4(globalPosition, 0.0, 1.0); +} + +vertex main0_out main0(main0_in in [[stage_in]], constant float2& uTileSize [[buffer(0)]], constant float2& uFramebufferSize [[buffer(1)]]) +{ + main0_out out = {}; + uint param = uint(in.aTileIndex); + uint2 param_1 = in.aTessCoord; + uint4 param_2 = in.aLineSegment; + float2 param_3 = uTileSize; + float2 param_4 = uFramebufferSize; + float2 param_5; + float2 param_6; + float4 _190 = computeVertexPosition(param, param_1, param_2, param_3, param_4, param_5, param_6); + out.vFrom = param_5; + out.vTo = param_6; + out.gl_Position = _190; + return out; +} + diff --git a/resources/shaders/metal/tile.fs.metal b/resources/shaders/metal/d3d9/tile.fs.metal similarity index 81% rename from resources/shaders/metal/tile.fs.metal rename to resources/shaders/metal/d3d9/tile.fs.metal index 1b2c7e9d..90346ffc 100644 --- a/resources/shaders/metal/tile.fs.metal +++ b/resources/shaders/metal/d3d9/tile.fs.metal @@ -6,7 +6,7 @@ using namespace metal; -constant float3 _1042 = {}; +constant float3 _1056 = {}; struct main0_out { @@ -19,6 +19,10 @@ struct main0_in float2 vColorTexCoord0 [[user(locn1)]]; float4 vBaseColor [[user(locn2)]]; float vTileCtrl [[user(locn3)]]; + float4 vFilterParams0 [[user(locn4)]]; + float4 vFilterParams1 [[user(locn5)]]; + float4 vFilterParams2 [[user(locn6)]]; + float vCtrl [[user(locn7)]]; }; // Implementation of the GLSL mod() function, which is slightly different than Metal fmod() @@ -71,16 +75,16 @@ float4 filterRadialGradient(thread const float2& colorTexCoord, thread const tex { ts = ts.yx; } - float _555; + float _569; if (ts.x >= 0.0) { - _555 = ts.x; + _569 = ts.x; } else { - _555 = ts.y; + _569 = ts.y; } - float t = _555; + float t = _569; color = colorTexture.sample(colorTextureSmplr, (uvOrigin + float2(fast::clamp(t, 0.0, 1.0), 0.0))); } return color; @@ -94,19 +98,19 @@ float4 filterBlur(thread const float2& colorTexCoord, thread const texture2d colorTexture, thread const sampler colorTextureSmplr, thread const float2& colorTexCoord, thread const float4& kernel0, thread const float& onePixel) { bool wide = kernel0.x > 0.0; - float _236; + float _250; if (wide) { float param = (-4.0) * onePixel; float2 param_1 = colorTexCoord; - _236 = filterTextSample1Tap(param, colorTexture, colorTextureSmplr, param_1); + _250 = filterTextSample1Tap(param, colorTexture, colorTextureSmplr, param_1); } else { - _236 = 0.0; + _250 = 0.0; } float param_2 = (-3.0) * onePixel; float2 param_3 = colorTexCoord; @@ -138,7 +142,7 @@ void filterTextSample9Tap(thread float4& outAlphaLeft, thread float& outAlphaCen float2 param_5 = colorTexCoord; float param_6 = (-1.0) * onePixel; float2 param_7 = colorTexCoord; - outAlphaLeft = float4(_236, filterTextSample1Tap(param_2, colorTexture, colorTextureSmplr, param_3), filterTextSample1Tap(param_4, colorTexture, colorTextureSmplr, param_5), filterTextSample1Tap(param_6, colorTexture, colorTextureSmplr, param_7)); + outAlphaLeft = float4(_250, filterTextSample1Tap(param_2, colorTexture, colorTextureSmplr, param_3), filterTextSample1Tap(param_4, colorTexture, colorTextureSmplr, param_5), filterTextSample1Tap(param_6, colorTexture, colorTextureSmplr, param_7)); float param_8 = 0.0; float2 param_9 = colorTexCoord; outAlphaCenter = filterTextSample1Tap(param_8, colorTexture, colorTextureSmplr, param_9); @@ -148,18 +152,18 @@ void filterTextSample9Tap(thread float4& outAlphaLeft, thread float& outAlphaCen float2 param_13 = colorTexCoord; float param_14 = 3.0 * onePixel; float2 param_15 = colorTexCoord; - float _296; + float _310; if (wide) { float param_16 = 4.0 * onePixel; float2 param_17 = colorTexCoord; - _296 = filterTextSample1Tap(param_16, colorTexture, colorTextureSmplr, param_17); + _310 = filterTextSample1Tap(param_16, colorTexture, colorTextureSmplr, param_17); } else { - _296 = 0.0; + _310 = 0.0; } - outAlphaRight = float4(filterTextSample1Tap(param_10, colorTexture, colorTextureSmplr, param_11), filterTextSample1Tap(param_12, colorTexture, colorTextureSmplr, param_13), filterTextSample1Tap(param_14, colorTexture, colorTextureSmplr, param_15), _296); + outAlphaRight = float4(filterTextSample1Tap(param_10, colorTexture, colorTextureSmplr, param_11), filterTextSample1Tap(param_12, colorTexture, colorTextureSmplr, param_13), filterTextSample1Tap(param_14, colorTexture, colorTextureSmplr, param_15), _310); } static inline __attribute__((always_inline)) @@ -309,34 +313,34 @@ float3 compositeScreen(thread const float3& destColor, thread const float3& srcC static inline __attribute__((always_inline)) float3 compositeSelect(thread const bool3& cond, thread const float3& ifTrue, thread const float3& ifFalse) { - float _726; + float _740; if (cond.x) { - _726 = ifTrue.x; + _740 = ifTrue.x; } else { - _726 = ifFalse.x; + _740 = ifFalse.x; } - float _737; + float _751; if (cond.y) { - _737 = ifTrue.y; + _751 = ifTrue.y; } else { - _737 = ifFalse.y; + _751 = ifFalse.y; } - float _748; + float _762; if (cond.z) { - _748 = ifTrue.z; + _762 = ifTrue.z; } else { - _748 = ifFalse.z; + _762 = ifFalse.z; } - return float3(_726, _737, _748); + return float3(_740, _751, _762); } static inline __attribute__((always_inline)) @@ -381,16 +385,16 @@ float3 compositeSoftLight(thread const float3& destColor, thread const float3& s static inline __attribute__((always_inline)) float compositeDivide(thread const float& num, thread const float& denom) { - float _762; + float _776; if (denom != 0.0) { - _762 = num / denom; + _776 = num / denom; } else { - _762 = 0.0; + _776 = 0.0; } - return _762; + return _776; } static inline __attribute__((always_inline)) @@ -400,25 +404,25 @@ float3 compositeRGBToHSL(thread const float3& rgb) float xMin = fast::min(fast::min(rgb.x, rgb.y), rgb.z); float c = v - xMin; float l = mix(xMin, v, 0.5); - float3 _868; + float3 _882; if (rgb.x == v) { - _868 = float3(0.0, rgb.yz); + _882 = float3(0.0, rgb.yz); } else { - float3 _881; + float3 _895; if (rgb.y == v) { - _881 = float3(2.0, rgb.zx); + _895 = float3(2.0, rgb.zx); } else { - _881 = float3(4.0, rgb.xy); + _895 = float3(4.0, rgb.xy); } - _868 = _881; + _882 = _895; } - float3 terms = _868; + float3 terms = _882; float param = ((terms.x * c) + terms.y) - terms.z; float param_1 = c; float h = 1.0471975803375244140625 * compositeDivide(param, param_1); @@ -555,29 +559,29 @@ float4 composite(thread const float4& srcColor, thread const texture2d de } static inline __attribute__((always_inline)) -void calculateColor(thread const int& tileCtrl, thread const int& ctrl, thread texture2d uMaskTexture0, thread const sampler uMaskTexture0Smplr, thread float2 uMaskTextureSize0, thread float3& vMaskTexCoord0, thread float4& vBaseColor, thread float2& vColorTexCoord0, thread texture2d uColorTexture0, thread const sampler uColorTexture0Smplr, thread texture2d uGammaLUT, thread const sampler uGammaLUTSmplr, thread float2 uColorTextureSize0, thread float4& gl_FragCoord, thread float2 uFramebufferSize, thread float4 uFilterParams0, thread float4 uFilterParams1, thread float4 uFilterParams2, thread texture2d uDestTexture, thread const sampler uDestTextureSmplr, thread float4& oFragColor) +float4 calculateColor(thread const float2& fragCoord, thread const texture2d colorTexture0, thread const sampler colorTexture0Smplr, thread const texture2d maskTexture0, thread const sampler maskTexture0Smplr, thread const texture2d destTexture, thread const sampler destTextureSmplr, thread const texture2d gammaLUT, thread const sampler gammaLUTSmplr, thread const float2& colorTextureSize0, thread const float2& maskTextureSize0, thread const float4& filterParams0, thread const float4& filterParams1, thread const float4& filterParams2, thread const float2& framebufferSize, thread const int& ctrl, thread const float3& maskTexCoord0, thread const float2& colorTexCoord0, thread const float4& baseColor, thread const int& tileCtrl) { int maskCtrl0 = (tileCtrl >> 0) & 3; float maskAlpha = 1.0; float param = maskAlpha; - float2 param_1 = uMaskTextureSize0; - float3 param_2 = vMaskTexCoord0; + float2 param_1 = maskTextureSize0; + float3 param_2 = maskTexCoord0; int param_3 = maskCtrl0; - maskAlpha = sampleMask(param, uMaskTexture0, uMaskTexture0Smplr, param_1, param_2, param_3); - float4 color = vBaseColor; + maskAlpha = sampleMask(param, maskTexture0, maskTexture0Smplr, param_1, param_2, param_3); + float4 color = baseColor; int color0Combine = (ctrl >> 6) & 3; if (color0Combine != 0) { int color0Filter = (ctrl >> 4) & 3; - float2 param_4 = vColorTexCoord0; - float2 param_5 = uColorTextureSize0; - float2 param_6 = gl_FragCoord.xy; - float2 param_7 = uFramebufferSize; - float4 param_8 = uFilterParams0; - float4 param_9 = uFilterParams1; - float4 param_10 = uFilterParams2; + float2 param_4 = colorTexCoord0; + float2 param_5 = colorTextureSize0; + float2 param_6 = fragCoord; + float2 param_7 = framebufferSize; + float4 param_8 = filterParams0; + float4 param_9 = filterParams1; + float4 param_10 = filterParams2; int param_11 = color0Filter; - float4 color0 = filterColor(param_4, uColorTexture0, uColorTexture0Smplr, uGammaLUT, uGammaLUTSmplr, param_5, param_6, param_7, param_8, param_9, param_10, param_11); + float4 color0 = filterColor(param_4, colorTexture0, colorTexture0Smplr, gammaLUT, gammaLUTSmplr, param_5, param_6, param_7, param_8, param_9, param_10, param_11); float4 param_12 = color; float4 param_13 = color0; int param_14 = color0Combine; @@ -586,21 +590,31 @@ void calculateColor(thread const int& tileCtrl, thread const int& ctrl, thread t color.w *= maskAlpha; int compositeOp = (ctrl >> 8) & 15; float4 param_15 = color; - float2 param_16 = uFramebufferSize; - float2 param_17 = gl_FragCoord.xy; + float2 param_16 = framebufferSize; + float2 param_17 = fragCoord; int param_18 = compositeOp; - color = composite(param_15, uDestTexture, uDestTextureSmplr, param_16, param_17, param_18); - float3 _1347 = color.xyz * color.w; - color = float4(_1347.x, _1347.y, _1347.z, color.w); - oFragColor = color; + color = composite(param_15, destTexture, destTextureSmplr, param_16, param_17, param_18); + float3 _1340 = color.xyz * color.w; + color = float4(_1340.x, _1340.y, _1340.z, color.w); + return color; } -fragment main0_out main0(main0_in in [[stage_in]], constant int& uCtrl [[buffer(6)]], constant float2& uMaskTextureSize0 [[buffer(0)]], constant float2& uColorTextureSize0 [[buffer(1)]], constant float2& uFramebufferSize [[buffer(2)]], constant float4& uFilterParams0 [[buffer(3)]], constant float4& uFilterParams1 [[buffer(4)]], constant float4& uFilterParams2 [[buffer(5)]], texture2d uMaskTexture0 [[texture(0)]], texture2d uColorTexture0 [[texture(1)]], texture2d uGammaLUT [[texture(2)]], texture2d uDestTexture [[texture(3)]], sampler uMaskTexture0Smplr [[sampler(0)]], sampler uColorTexture0Smplr [[sampler(1)]], sampler uGammaLUTSmplr [[sampler(2)]], sampler uDestTextureSmplr [[sampler(3)]], float4 gl_FragCoord [[position]]) +fragment main0_out main0(main0_in in [[stage_in]], constant float2& uColorTextureSize0 [[buffer(0)]], constant float2& uMaskTextureSize0 [[buffer(1)]], constant float2& uFramebufferSize [[buffer(2)]], texture2d uColorTexture0 [[texture(0)]], texture2d uMaskTexture0 [[texture(1)]], texture2d uDestTexture [[texture(2)]], texture2d uGammaLUT [[texture(3)]], sampler uColorTexture0Smplr [[sampler(0)]], sampler uMaskTexture0Smplr [[sampler(1)]], sampler uDestTextureSmplr [[sampler(2)]], sampler uGammaLUTSmplr [[sampler(3)]], float4 gl_FragCoord [[position]]) { main0_out out = {}; - int param = int(in.vTileCtrl); - int param_1 = uCtrl; - calculateColor(param, param_1, uMaskTexture0, uMaskTexture0Smplr, uMaskTextureSize0, in.vMaskTexCoord0, in.vBaseColor, in.vColorTexCoord0, uColorTexture0, uColorTexture0Smplr, uGammaLUT, uGammaLUTSmplr, uColorTextureSize0, gl_FragCoord, uFramebufferSize, uFilterParams0, uFilterParams1, uFilterParams2, uDestTexture, uDestTextureSmplr, out.oFragColor); + float2 param = gl_FragCoord.xy; + float2 param_1 = uColorTextureSize0; + float2 param_2 = uMaskTextureSize0; + float4 param_3 = in.vFilterParams0; + float4 param_4 = in.vFilterParams1; + float4 param_5 = in.vFilterParams2; + float2 param_6 = uFramebufferSize; + int param_7 = int(in.vCtrl); + float3 param_8 = in.vMaskTexCoord0; + float2 param_9 = in.vColorTexCoord0; + float4 param_10 = in.vBaseColor; + int param_11 = int(in.vTileCtrl); + out.oFragColor = calculateColor(param, uColorTexture0, uColorTexture0Smplr, uMaskTexture0, uMaskTexture0Smplr, uDestTexture, uDestTextureSmplr, uGammaLUT, uGammaLUTSmplr, param_1, param_2, param_3, param_4, param_5, param_6, param_7, param_8, param_9, param_10, param_11); return out; } diff --git a/resources/shaders/metal/d3d9/tile.vs.metal b/resources/shaders/metal/d3d9/tile.vs.metal new file mode 100644 index 00000000..7e83626b --- /dev/null +++ b/resources/shaders/metal/d3d9/tile.vs.metal @@ -0,0 +1,130 @@ +// Automatically generated from files in pathfinder/shaders/. Do not edit! +#pragma clang diagnostic ignored "-Wmissing-prototypes" + +#include +#include + +using namespace metal; + +struct main0_out +{ + float3 vMaskTexCoord0 [[user(locn0)]]; + float2 vColorTexCoord0 [[user(locn1)]]; + float4 vBaseColor [[user(locn2)]]; + float vTileCtrl [[user(locn3)]]; + float4 vFilterParams0 [[user(locn4)]]; + float4 vFilterParams1 [[user(locn5)]]; + float4 vFilterParams2 [[user(locn6)]]; + float vCtrl [[user(locn7)]]; + float4 gl_Position [[position]]; +}; + +struct main0_in +{ + int2 aTileOffset [[attribute(0)]]; + int2 aTileOrigin [[attribute(1)]]; + uint4 aMaskTexCoord0 [[attribute(2)]]; + int2 aCtrlBackdrop [[attribute(3)]]; + int aPathIndex [[attribute(4)]]; + int aColor [[attribute(5)]]; +}; + +static inline __attribute__((always_inline)) +float4 fetchUnscaled(thread const texture2d srcTexture, thread const sampler srcTextureSmplr, thread const float2& scale, thread const float2& originCoord, thread const int& entry) +{ + return srcTexture.sample(srcTextureSmplr, (((originCoord + float2(0.5)) + float2(float(entry), 0.0)) * scale), level(0.0)); +} + +static inline __attribute__((always_inline)) +void computeTileVaryings(thread const float2& position, thread const int& colorEntry, thread const texture2d textureMetadata, thread const sampler textureMetadataSmplr, thread const int2& textureMetadataSize, thread float2& outColorTexCoord0, thread float4& outBaseColor, thread float4& outFilterParams0, thread float4& outFilterParams1, thread float4& outFilterParams2, thread int& outCtrl) +{ + float2 metadataScale = float2(1.0) / float2(textureMetadataSize); + float2 metadataEntryCoord = float2(float((colorEntry % 128) * 8), float(colorEntry / 128)); + float2 param = metadataScale; + float2 param_1 = metadataEntryCoord; + int param_2 = 0; + float4 colorTexMatrix0 = fetchUnscaled(textureMetadata, textureMetadataSmplr, param, param_1, param_2); + float2 param_3 = metadataScale; + float2 param_4 = metadataEntryCoord; + int param_5 = 1; + float4 colorTexOffsets = fetchUnscaled(textureMetadata, textureMetadataSmplr, param_3, param_4, param_5); + float2 param_6 = metadataScale; + float2 param_7 = metadataEntryCoord; + int param_8 = 2; + float4 baseColor = fetchUnscaled(textureMetadata, textureMetadataSmplr, param_6, param_7, param_8); + float2 param_9 = metadataScale; + float2 param_10 = metadataEntryCoord; + int param_11 = 3; + float4 filterParams0 = fetchUnscaled(textureMetadata, textureMetadataSmplr, param_9, param_10, param_11); + float2 param_12 = metadataScale; + float2 param_13 = metadataEntryCoord; + int param_14 = 4; + float4 filterParams1 = fetchUnscaled(textureMetadata, textureMetadataSmplr, param_12, param_13, param_14); + float2 param_15 = metadataScale; + float2 param_16 = metadataEntryCoord; + int param_17 = 5; + float4 filterParams2 = fetchUnscaled(textureMetadata, textureMetadataSmplr, param_15, param_16, param_17); + float2 param_18 = metadataScale; + float2 param_19 = metadataEntryCoord; + int param_20 = 6; + float4 extra = fetchUnscaled(textureMetadata, textureMetadataSmplr, param_18, param_19, param_20); + outColorTexCoord0 = (float2x2(float2(colorTexMatrix0.xy), float2(colorTexMatrix0.zw)) * position) + colorTexOffsets.xy; + outBaseColor = baseColor; + outFilterParams0 = filterParams0; + outFilterParams1 = filterParams1; + outFilterParams2 = filterParams2; + outCtrl = int(extra.x); +} + +vertex main0_out main0(main0_in in [[stage_in]], constant int2& uZBufferSize [[buffer(1)]], constant int2& uTextureMetadataSize [[buffer(2)]], constant float2& uTileSize [[buffer(0)]], constant float4x4& uTransform [[buffer(3)]], texture2d uZBuffer [[texture(0)]], texture2d uTextureMetadata [[texture(1)]], sampler uZBufferSmplr [[sampler(0)]], sampler uTextureMetadataSmplr [[sampler(1)]]) +{ + main0_out out = {}; + float2 tileOrigin = float2(in.aTileOrigin); + float2 tileOffset = float2(in.aTileOffset); + float2 position = (tileOrigin + tileOffset) * uTileSize; + int4 zValue = int4(uZBuffer.sample(uZBufferSmplr, ((tileOrigin + float2(0.5)) / float2(uZBufferSize)), level(0.0)) * 255.0); + if (in.aPathIndex < (((zValue.x | (zValue.y << 8)) | (zValue.z << 16)) | (zValue.w << 24))) + { + out.gl_Position = float4(0.0); + return out; + } + uint2 maskTileCoord = uint2(in.aMaskTexCoord0.x, in.aMaskTexCoord0.y + (256u * in.aMaskTexCoord0.z)); + float2 maskTexCoord0 = (float2(maskTileCoord) + tileOffset) * uTileSize; + bool _244 = in.aCtrlBackdrop.y == 0; + bool _250; + if (_244) + { + _250 = in.aMaskTexCoord0.w != 0u; + } + else + { + _250 = _244; + } + if (_250) + { + out.gl_Position = float4(0.0); + return out; + } + float2 param = position; + int param_1 = in.aColor; + int2 param_2 = uTextureMetadataSize; + float2 param_3; + float4 param_4; + float4 param_5; + float4 param_6; + float4 param_7; + int param_8; + computeTileVaryings(param, param_1, uTextureMetadata, uTextureMetadataSmplr, param_2, param_3, param_4, param_5, param_6, param_7, param_8); + out.vColorTexCoord0 = param_3; + out.vBaseColor = param_4; + out.vFilterParams0 = param_5; + out.vFilterParams1 = param_6; + out.vFilterParams2 = param_7; + int ctrl = param_8; + out.vTileCtrl = float(in.aCtrlBackdrop.x); + out.vCtrl = float(ctrl); + out.vMaskTexCoord0 = float3(maskTexCoord0, float(in.aCtrlBackdrop.y)); + out.gl_Position = uTransform * float4(position, 0.0, 1.0); + return out; +} + diff --git a/resources/shaders/metal/d3d9/tile_clip_combine.fs.metal b/resources/shaders/metal/d3d9/tile_clip_combine.fs.metal new file mode 100644 index 00000000..f0fd36a2 --- /dev/null +++ b/resources/shaders/metal/d3d9/tile_clip_combine.fs.metal @@ -0,0 +1,26 @@ +// Automatically generated from files in pathfinder/shaders/. Do not edit! +#include +#include + +using namespace metal; + +struct main0_out +{ + float4 oFragColor [[color(0)]]; +}; + +struct main0_in +{ + float2 vTexCoord0 [[user(locn0)]]; + float vBackdrop0 [[user(locn1)]]; + float2 vTexCoord1 [[user(locn2)]]; + float vBackdrop1 [[user(locn3)]]; +}; + +fragment main0_out main0(main0_in in [[stage_in]], texture2d uSrc [[texture(0)]], sampler uSrcSmplr [[sampler(0)]]) +{ + main0_out out = {}; + out.oFragColor = fast::min(abs(uSrc.sample(uSrcSmplr, in.vTexCoord0) + float4(in.vBackdrop0)), abs(uSrc.sample(uSrcSmplr, in.vTexCoord1) + float4(in.vBackdrop1))); + return out; +} + diff --git a/resources/shaders/metal/d3d9/tile_clip_combine.vs.metal b/resources/shaders/metal/d3d9/tile_clip_combine.vs.metal new file mode 100644 index 00000000..2a7864a7 --- /dev/null +++ b/resources/shaders/metal/d3d9/tile_clip_combine.vs.metal @@ -0,0 +1,44 @@ +// Automatically generated from files in pathfinder/shaders/. Do not edit! +#include +#include + +using namespace metal; + +struct main0_out +{ + float2 vTexCoord0 [[user(locn0)]]; + float vBackdrop0 [[user(locn1)]]; + float2 vTexCoord1 [[user(locn2)]]; + float vBackdrop1 [[user(locn3)]]; + float4 gl_Position [[position]]; +}; + +struct main0_in +{ + int2 aTileOffset [[attribute(0)]]; + int aDestTileIndex [[attribute(1)]]; + int aDestBackdrop [[attribute(2)]]; + int aSrcTileIndex [[attribute(3)]]; + int aSrcBackdrop [[attribute(4)]]; +}; + +vertex main0_out main0(main0_in in [[stage_in]], constant float2& uFramebufferSize [[buffer(0)]]) +{ + main0_out out = {}; + float2 destPosition = float2(int2(in.aDestTileIndex % 256, in.aDestTileIndex / 256) + in.aTileOffset); + float2 srcPosition = float2(int2(in.aSrcTileIndex % 256, in.aSrcTileIndex / 256) + in.aTileOffset); + destPosition *= (float2(16.0, 4.0) / uFramebufferSize); + srcPosition *= (float2(16.0, 4.0) / uFramebufferSize); + out.vTexCoord0 = destPosition; + out.vTexCoord1 = srcPosition; + out.vBackdrop0 = float(in.aDestBackdrop); + out.vBackdrop1 = float(in.aSrcBackdrop); + if (in.aDestTileIndex < 0) + { + destPosition = float2(0.0); + } + destPosition.y = 1.0 - destPosition.y; + out.gl_Position = float4(mix(float2(-1.0), float2(1.0), destPosition), 0.0, 1.0); + return out; +} + diff --git a/resources/shaders/metal/tile_clip.fs.metal b/resources/shaders/metal/d3d9/tile_clip_copy.fs.metal similarity index 72% rename from resources/shaders/metal/tile_clip.fs.metal rename to resources/shaders/metal/d3d9/tile_clip_copy.fs.metal index de4bf10a..50cb0e43 100644 --- a/resources/shaders/metal/tile_clip.fs.metal +++ b/resources/shaders/metal/d3d9/tile_clip_copy.fs.metal @@ -12,13 +12,12 @@ struct main0_out struct main0_in { float2 vTexCoord [[user(locn0)]]; - float vBackdrop [[user(locn1)]]; }; fragment main0_out main0(main0_in in [[stage_in]], texture2d uSrc [[texture(0)]], sampler uSrcSmplr [[sampler(0)]]) { main0_out out = {}; - out.oFragColor = fast::clamp(abs(uSrc.sample(uSrcSmplr, in.vTexCoord) + float4(in.vBackdrop)), float4(0.0), float4(1.0)); + out.oFragColor = uSrc.sample(uSrcSmplr, in.vTexCoord); return out; } diff --git a/resources/shaders/metal/d3d9/tile_clip_copy.vs.metal b/resources/shaders/metal/d3d9/tile_clip_copy.vs.metal new file mode 100644 index 00000000..979ac7f8 --- /dev/null +++ b/resources/shaders/metal/d3d9/tile_clip_copy.vs.metal @@ -0,0 +1,33 @@ +// Automatically generated from files in pathfinder/shaders/. Do not edit! +#include +#include + +using namespace metal; + +struct main0_out +{ + float2 vTexCoord [[user(locn0)]]; + float4 gl_Position [[position]]; +}; + +struct main0_in +{ + int2 aTileOffset [[attribute(0)]]; + int aTileIndex [[attribute(1)]]; +}; + +vertex main0_out main0(main0_in in [[stage_in]], constant float2& uFramebufferSize [[buffer(0)]]) +{ + main0_out out = {}; + float2 position = float2(int2(in.aTileIndex % 256, in.aTileIndex / 256) + in.aTileOffset); + position *= (float2(16.0, 4.0) / uFramebufferSize); + out.vTexCoord = position; + if (in.aTileIndex < 0) + { + position = float2(0.0); + } + position.y = 1.0 - position.y; + out.gl_Position = float4(mix(float2(-1.0), float2(1.0), position), 0.0, 1.0); + return out; +} + diff --git a/resources/shaders/metal/tile_copy.fs.metal b/resources/shaders/metal/d3d9/tile_copy.fs.metal similarity index 100% rename from resources/shaders/metal/tile_copy.fs.metal rename to resources/shaders/metal/d3d9/tile_copy.fs.metal diff --git a/resources/shaders/metal/tile_copy.vs.metal b/resources/shaders/metal/d3d9/tile_copy.vs.metal similarity index 100% rename from resources/shaders/metal/tile_copy.vs.metal rename to resources/shaders/metal/d3d9/tile_copy.vs.metal diff --git a/resources/shaders/metal/fill.vs.metal b/resources/shaders/metal/fill.vs.metal deleted file mode 100644 index a8cf9a86..00000000 --- a/resources/shaders/metal/fill.vs.metal +++ /dev/null @@ -1,68 +0,0 @@ -// Automatically generated from files in pathfinder/shaders/. Do not edit! -#pragma clang diagnostic ignored "-Wmissing-prototypes" - -#include -#include - -using namespace metal; - -struct main0_out -{ - float2 vFrom [[user(locn0)]]; - float2 vTo [[user(locn1)]]; - float4 gl_Position [[position]]; -}; - -struct main0_in -{ - uint2 aTessCoord [[attribute(0)]]; - uint aFromPx [[attribute(1)]]; - uint aToPx [[attribute(2)]]; - float2 aFromSubpx [[attribute(3)]]; - float2 aToSubpx [[attribute(4)]]; - uint aTileIndex [[attribute(5)]]; -}; - -static inline __attribute__((always_inline)) -float2 computeTileOffset(thread const uint& tileIndex, thread const float& stencilTextureWidth, thread float2 uTileSize) -{ - uint tilesPerRow = uint(stencilTextureWidth / uTileSize.x); - uint2 tileOffset = uint2(tileIndex % tilesPerRow, tileIndex / tilesPerRow); - return (float2(tileOffset) * uTileSize) * float2(1.0, 0.25); -} - -vertex main0_out main0(main0_in in [[stage_in]], constant float2& uTileSize [[buffer(0)]], constant float2& uFramebufferSize [[buffer(1)]]) -{ - main0_out out = {}; - uint param = in.aTileIndex; - float param_1 = uFramebufferSize.x; - float2 tileOrigin = computeTileOffset(param, param_1, uTileSize); - float2 from = float2(float(in.aFromPx & 15u), float(in.aFromPx >> 4u)) + in.aFromSubpx; - float2 to = float2(float(in.aToPx & 15u), float(in.aToPx >> 4u)) + in.aToSubpx; - float2 position; - if (in.aTessCoord.x == 0u) - { - position.x = floor(fast::min(from.x, to.x)); - } - else - { - position.x = ceil(fast::max(from.x, to.x)); - } - if (in.aTessCoord.y == 0u) - { - position.y = floor(fast::min(from.y, to.y)); - } - else - { - position.y = uTileSize.y; - } - position.y = floor(position.y * 0.25); - float2 offset = float2(0.0, 1.5) - (position * float2(1.0, 4.0)); - out.vFrom = from + offset; - out.vTo = to + offset; - float2 globalPosition = (((tileOrigin + position) / uFramebufferSize) * 2.0) - float2(1.0); - globalPosition.y = -globalPosition.y; - out.gl_Position = float4(globalPosition, 0.0, 1.0); - return out; -} - diff --git a/resources/shaders/metal/tile.vs.metal b/resources/shaders/metal/tile.vs.metal deleted file mode 100644 index 6b297b65..00000000 --- a/resources/shaders/metal/tile.vs.metal +++ /dev/null @@ -1,48 +0,0 @@ -// Automatically generated from files in pathfinder/shaders/. Do not edit! -#include -#include - -using namespace metal; - -struct main0_out -{ - float3 vMaskTexCoord0 [[user(locn0)]]; - float2 vColorTexCoord0 [[user(locn1)]]; - float4 vBaseColor [[user(locn2)]]; - float vTileCtrl [[user(locn3)]]; - float4 gl_Position [[position]]; -}; - -struct main0_in -{ - int2 aTileOffset [[attribute(0)]]; - int2 aTileOrigin [[attribute(1)]]; - uint2 aMaskTexCoord0 [[attribute(2)]]; - int2 aMaskBackdrop [[attribute(3)]]; - int aColor [[attribute(4)]]; - int aTileCtrl [[attribute(5)]]; -}; - -vertex main0_out main0(main0_in in [[stage_in]], constant int2& uTextureMetadataSize [[buffer(1)]], constant float2& uTileSize [[buffer(0)]], constant float4x4& uTransform [[buffer(2)]], texture2d uTextureMetadata [[texture(0)]], sampler uTextureMetadataSmplr [[sampler(0)]]) -{ - main0_out out = {}; - float2 tileOrigin = float2(in.aTileOrigin); - float2 tileOffset = float2(in.aTileOffset); - float2 position = (tileOrigin + tileOffset) * uTileSize; - float2 maskTexCoord0 = (float2(in.aMaskTexCoord0) + tileOffset) * uTileSize; - float2 textureMetadataScale = float2(1.0) / float2(uTextureMetadataSize); - float2 metadataEntryCoord = float2(float((in.aColor % 128) * 4), float(in.aColor / 128)); - float2 colorTexMatrix0Coord = (metadataEntryCoord + float2(0.5)) * textureMetadataScale; - float2 colorTexOffsetsCoord = (metadataEntryCoord + float2(1.5, 0.5)) * textureMetadataScale; - float2 baseColorCoord = (metadataEntryCoord + float2(2.5, 0.5)) * textureMetadataScale; - float4 colorTexMatrix0 = uTextureMetadata.sample(uTextureMetadataSmplr, colorTexMatrix0Coord, level(0.0)); - float4 colorTexOffsets = uTextureMetadata.sample(uTextureMetadataSmplr, colorTexOffsetsCoord, level(0.0)); - float4 baseColor = uTextureMetadata.sample(uTextureMetadataSmplr, baseColorCoord, level(0.0)); - out.vColorTexCoord0 = (float2x2(float2(colorTexMatrix0.xy), float2(colorTexMatrix0.zw)) * position) + colorTexOffsets.xy; - out.vMaskTexCoord0 = float3(maskTexCoord0, float(in.aMaskBackdrop.x)); - out.vBaseColor = baseColor; - out.vTileCtrl = float(in.aTileCtrl); - out.gl_Position = uTransform * float4(position, 0.0, 1.0); - return out; -} - diff --git a/resources/shaders/metal/tile_clip.vs.metal b/resources/shaders/metal/tile_clip.vs.metal deleted file mode 100644 index 3e3a6baf..00000000 --- a/resources/shaders/metal/tile_clip.vs.metal +++ /dev/null @@ -1,32 +0,0 @@ -// Automatically generated from files in pathfinder/shaders/. Do not edit! -#include -#include - -using namespace metal; - -struct main0_out -{ - float2 vTexCoord [[user(locn0)]]; - float vBackdrop [[user(locn1)]]; - float4 gl_Position [[position]]; -}; - -struct main0_in -{ - int2 aTileOffset [[attribute(0)]]; - int2 aDestTileOrigin [[attribute(1)]]; - int2 aSrcTileOrigin [[attribute(2)]]; - int aSrcBackdrop [[attribute(3)]]; -}; - -vertex main0_out main0(main0_in in [[stage_in]]) -{ - main0_out out = {}; - float2 destPosition = float2(in.aDestTileOrigin + in.aTileOffset) / float2(256.0); - float2 srcPosition = float2(in.aSrcTileOrigin + in.aTileOffset) / float2(256.0); - out.vTexCoord = srcPosition; - out.vBackdrop = float(in.aSrcBackdrop); - out.gl_Position = float4(mix(float2(-1.0), float2(1.0), destPosition), 0.0, 1.0); - return out; -} - diff --git a/shaders/fill.fs.glsl b/shaders/d3d9/fill.fs.glsl similarity index 95% rename from shaders/fill.fs.glsl rename to shaders/d3d9/fill.fs.glsl index 6ed65f9c..9543f9c3 100644 --- a/shaders/fill.fs.glsl +++ b/shaders/d3d9/fill.fs.glsl @@ -18,7 +18,7 @@ precision highp float; precision highp sampler2D; #endif -#include "fill.inc.glsl" +#include "fill_area.inc.glsl" uniform sampler2D uAreaLUT; diff --git a/shaders/fill.vs.glsl b/shaders/d3d9/fill.vs.glsl similarity index 51% rename from shaders/fill.vs.glsl rename to shaders/d3d9/fill.vs.glsl index d513b5ef..640beb04 100644 --- a/shaders/fill.vs.glsl +++ b/shaders/d3d9/fill.vs.glsl @@ -10,6 +10,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#extension GL_GOOGLE_include_directive : enable + precision highp float; #ifdef GL_ES @@ -20,36 +22,39 @@ uniform vec2 uFramebufferSize; uniform vec2 uTileSize; in uvec2 aTessCoord; -in uint aFromPx; -in uint aToPx; -in vec2 aFromSubpx; -in vec2 aToSubpx; -in uint aTileIndex; +in uvec4 aLineSegment; +in int aTileIndex; out vec2 vFrom; out vec2 vTo; -vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth) { - uint tilesPerRow = uint(stencilTextureWidth / uTileSize.x); +vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth, vec2 tileSize) { + uint tilesPerRow = uint(stencilTextureWidth / tileSize.x); uvec2 tileOffset = uvec2(tileIndex % tilesPerRow, tileIndex / tilesPerRow); - return vec2(tileOffset) * uTileSize * vec2(1.0, 0.25); + return vec2(tileOffset) * tileSize * vec2(1.0, 0.25); } -void main() { - vec2 tileOrigin = computeTileOffset(aTileIndex, uFramebufferSize.x); +vec4 computeVertexPosition(uint tileIndex, + uvec2 tessCoord, + uvec4 packedLineSegment, + vec2 tileSize, + vec2 framebufferSize, + out vec2 outFrom, + out vec2 outTo) { + vec2 tileOrigin = computeTileOffset(uint(tileIndex), framebufferSize.x, tileSize); - vec2 from = vec2(aFromPx & 15u, aFromPx >> 4u) + aFromSubpx; - vec2 to = vec2(aToPx & 15u, aToPx >> 4u) + aToSubpx; + vec4 lineSegment = vec4(packedLineSegment) / 256.0; + vec2 from = lineSegment.xy, to = lineSegment.zw; vec2 position; - if (aTessCoord.x == 0u) + if (tessCoord.x == 0u) position.x = floor(min(from.x, to.x)); else position.x = ceil(max(from.x, to.x)); - if (aTessCoord.y == 0u) + if (tessCoord.y == 0u) position.y = floor(min(from.y, to.y)); else - position.y = uTileSize.y; + position.y = tileSize.y; position.y = floor(position.y * 0.25); // Since each fragment corresponds to 4 pixels on a scanline, the varying interpolation will @@ -57,12 +62,22 @@ void main() { // do our coverage calculation on the center of the first pixel in the strip instead, at pixel // offset 0.5. This adjustment of 1.5 accomplishes that. vec2 offset = vec2(0.0, 1.5) - position * vec2(1.0, 4.0); - vFrom = from + offset; - vTo = to + offset; + outFrom = from + offset; + outTo = to + offset; - vec2 globalPosition = (tileOrigin + position) / uFramebufferSize * 2.0 - 1.0; + vec2 globalPosition = (tileOrigin + position) / framebufferSize * 2.0 - 1.0; #ifdef PF_ORIGIN_UPPER_LEFT globalPosition.y = -globalPosition.y; #endif - gl_Position = vec4(globalPosition, 0.0, 1.0); + return vec4(globalPosition, 0.0, 1.0); +} + +void main() { + gl_Position = computeVertexPosition(uint(aTileIndex), + aTessCoord, + aLineSegment, + uTileSize, + uFramebufferSize, + vFrom, + vTo); } diff --git a/shaders/d3d9/tile.fs.glsl b/shaders/d3d9/tile.fs.glsl new file mode 100644 index 00000000..25afb515 --- /dev/null +++ b/shaders/d3d9/tile.fs.glsl @@ -0,0 +1,63 @@ +#version 330 + +// pathfinder/shaders/tile.fs.glsl +// +// Copyright © 2020 The Pathfinder Project Developers. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#extension GL_GOOGLE_include_directive : enable + +precision highp float; + +#ifdef GL_ES +precision highp sampler2D; +#endif + +#include "tile_fragment.inc.glsl" + +uniform sampler2D uColorTexture0; +uniform sampler2D uMaskTexture0; +uniform sampler2D uDestTexture; +uniform sampler2D uGammaLUT; +uniform vec2 uColorTextureSize0; +uniform vec2 uMaskTextureSize0; +uniform vec2 uFramebufferSize; + +in vec3 vMaskTexCoord0; +in vec2 vColorTexCoord0; +in vec4 vBaseColor; +in float vTileCtrl; +in vec4 vFilterParams0; +in vec4 vFilterParams1; +in vec4 vFilterParams2; +in float vCtrl; + +out vec4 oFragColor; + +// Entry point +// +// TODO(pcwalton): Generate this dynamically. + +void main() { + oFragColor = calculateColor(gl_FragCoord.xy, + uColorTexture0, + uMaskTexture0, + uDestTexture, + uGammaLUT, + uColorTextureSize0, + uMaskTextureSize0, + vFilterParams0, + vFilterParams1, + vFilterParams2, + uFramebufferSize, + int(vCtrl), + vMaskTexCoord0, + vColorTexCoord0, + vBaseColor, + int(vTileCtrl)); +} diff --git a/shaders/d3d9/tile.vs.glsl b/shaders/d3d9/tile.vs.glsl new file mode 100644 index 00000000..bab4d802 --- /dev/null +++ b/shaders/d3d9/tile.vs.glsl @@ -0,0 +1,79 @@ +#version 330 + +// pathfinder/shaders/tile.vs.glsl +// +// Copyright © 2020 The Pathfinder Project Developers. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#extension GL_GOOGLE_include_directive : enable + +precision highp float; + +#ifdef GL_ES +precision highp sampler2D; +#endif + +#include "tile_vertex.inc.glsl" + +uniform mat4 uTransform; +uniform vec2 uTileSize; +uniform sampler2D uTextureMetadata; +uniform ivec2 uTextureMetadataSize; +uniform sampler2D uZBuffer; +uniform ivec2 uZBufferSize; + +in ivec2 aTileOffset; +in ivec2 aTileOrigin; +in uvec4 aMaskTexCoord0; +in ivec2 aCtrlBackdrop; +in int aPathIndex; +in int aColor; + +out vec3 vMaskTexCoord0; +out vec2 vColorTexCoord0; +out vec4 vBaseColor; +out float vTileCtrl; +out vec4 vFilterParams0; +out vec4 vFilterParams1; +out vec4 vFilterParams2; +out float vCtrl; + +void main() { + vec2 tileOrigin = vec2(aTileOrigin), tileOffset = vec2(aTileOffset); + vec2 position = (tileOrigin + tileOffset) * uTileSize; + + ivec4 zValue = ivec4(texture(uZBuffer, (tileOrigin + vec2(0.5)) / vec2(uZBufferSize)) * 255.0); + if (aPathIndex < (zValue.x | (zValue.y << 8) | (zValue.z << 16) | (zValue.w << 24))) { + gl_Position = vec4(0.0); + return; + } + + uvec2 maskTileCoord = uvec2(aMaskTexCoord0.x, aMaskTexCoord0.y + 256u * aMaskTexCoord0.z); + vec2 maskTexCoord0 = (vec2(maskTileCoord) + tileOffset) * uTileSize; + if (aCtrlBackdrop.y == 0 && aMaskTexCoord0.w != 0u) { + gl_Position = vec4(0.0); + return; + } + + int ctrl; + computeTileVaryings(position, + aColor, + uTextureMetadata, + uTextureMetadataSize, + vColorTexCoord0, + vBaseColor, + vFilterParams0, + vFilterParams1, + vFilterParams2, + ctrl); + + vTileCtrl = float(aCtrlBackdrop.x); + vCtrl = float(ctrl); + vMaskTexCoord0 = vec3(maskTexCoord0, float(aCtrlBackdrop.y)); + gl_Position = uTransform * vec4(position, 0.0, 1.0); +} diff --git a/shaders/d3d9/tile_clip_combine.fs.glsl b/shaders/d3d9/tile_clip_combine.fs.glsl new file mode 100644 index 00000000..ccb2523b --- /dev/null +++ b/shaders/d3d9/tile_clip_combine.fs.glsl @@ -0,0 +1,31 @@ +#version 330 + +// pathfinder/shaders/tile_clip_combine.fs.glsl +// +// Copyright © 2020 The Pathfinder Project Developers. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +precision highp float; + +#ifdef GL_ES +precision highp sampler2D; +#endif + +uniform sampler2D uSrc; + +in vec2 vTexCoord0; +in float vBackdrop0; +in vec2 vTexCoord1; +in float vBackdrop1; + +out vec4 oFragColor; + +void main() { + oFragColor = min(abs(texture(uSrc, vTexCoord0) + vBackdrop0), + abs(texture(uSrc, vTexCoord1) + vBackdrop1)); +} diff --git a/shaders/d3d9/tile_clip_combine.vs.glsl b/shaders/d3d9/tile_clip_combine.vs.glsl new file mode 100644 index 00000000..03e6236b --- /dev/null +++ b/shaders/d3d9/tile_clip_combine.vs.glsl @@ -0,0 +1,51 @@ +#version 330 + +// pathfinder/shaders/tile_clip_combine.vs.glsl +// +// Copyright © 2020 The Pathfinder Project Developers. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +precision highp float; + +#ifdef GL_ES +precision highp sampler2D; +#endif + +uniform vec2 uFramebufferSize; + +in ivec2 aTileOffset; +in int aDestTileIndex; +in int aDestBackdrop; +in int aSrcTileIndex; +in int aSrcBackdrop; + +out vec2 vTexCoord0; +out float vBackdrop0; +out vec2 vTexCoord1; +out float vBackdrop1; + +void main() { + vec2 destPosition = vec2(ivec2(aDestTileIndex % 256, aDestTileIndex / 256) + aTileOffset); + vec2 srcPosition = vec2(ivec2(aSrcTileIndex % 256, aSrcTileIndex / 256) + aTileOffset); + destPosition *= vec2(16.0, 4.0) / uFramebufferSize; + srcPosition *= vec2(16.0, 4.0) / uFramebufferSize; + + vTexCoord0 = destPosition; + vTexCoord1 = srcPosition; + + vBackdrop0 = float(aDestBackdrop); + vBackdrop1 = float(aSrcBackdrop); + + if (aDestTileIndex < 0) + destPosition = vec2(0.0); + +#ifdef PF_ORIGIN_UPPER_LEFT + destPosition.y = 1.0 - destPosition.y; +#endif + gl_Position = vec4(mix(vec2(-1.0), vec2(1.0), destPosition), 0.0, 1.0); +} diff --git a/shaders/tile_clip.fs.glsl b/shaders/d3d9/tile_clip_copy.fs.glsl similarity index 79% rename from shaders/tile_clip.fs.glsl rename to shaders/d3d9/tile_clip_copy.fs.glsl index e6c7b6ad..fcbb569f 100644 --- a/shaders/tile_clip.fs.glsl +++ b/shaders/d3d9/tile_clip_copy.fs.glsl @@ -1,6 +1,6 @@ #version 330 -// pathfinder/shaders/tile_clip.fs.glsl +// pathfinder/shaders/tile_clip_copy.fs.glsl // // Copyright © 2020 The Pathfinder Project Developers. // @@ -19,10 +19,9 @@ precision highp sampler2D; uniform sampler2D uSrc; in vec2 vTexCoord; -in float vBackdrop; out vec4 oFragColor; void main() { - oFragColor = clamp(abs(texture(uSrc, vTexCoord) + vBackdrop), 0.0, 1.0); + oFragColor = texture(uSrc, vTexCoord); } diff --git a/shaders/tile_clip.vs.glsl b/shaders/d3d9/tile_clip_copy.vs.glsl similarity index 52% rename from shaders/tile_clip.vs.glsl rename to shaders/d3d9/tile_clip_copy.vs.glsl index 47186462..cdc25913 100644 --- a/shaders/tile_clip.vs.glsl +++ b/shaders/d3d9/tile_clip_copy.vs.glsl @@ -1,6 +1,6 @@ #version 330 -// pathfinder/shaders/tile_clip.vs.glsl +// pathfinder/shaders/tile_clip_copy.vs.glsl // // Copyright © 2020 The Pathfinder Project Developers. // @@ -16,18 +16,24 @@ precision highp float; precision highp sampler2D; #endif +uniform vec2 uFramebufferSize; + in ivec2 aTileOffset; -in ivec2 aDestTileOrigin; -in ivec2 aSrcTileOrigin; -in int aSrcBackdrop; +in int aTileIndex; out vec2 vTexCoord; -out float vBackdrop; void main() { - vec2 destPosition = vec2(aDestTileOrigin + aTileOffset) / vec2(256.0); - vec2 srcPosition = vec2(aSrcTileOrigin + aTileOffset) / vec2(256.0); - vTexCoord = srcPosition; - vBackdrop = float(aSrcBackdrop); - gl_Position = vec4(mix(vec2(-1.0), vec2(1.0), destPosition), 0.0, 1.0); + vec2 position = vec2(ivec2(aTileIndex % 256, aTileIndex / 256) + aTileOffset); + position *= vec2(16.0, 4.0) / uFramebufferSize; + + vTexCoord = position; + + if (aTileIndex < 0) + position = vec2(0.0); + +#ifdef PF_ORIGIN_UPPER_LEFT + position.y = 1.0 - position.y; +#endif + gl_Position = vec4(mix(vec2(-1.0), vec2(1.0), position), 0.0, 1.0); } diff --git a/shaders/tile_copy.fs.glsl b/shaders/d3d9/tile_copy.fs.glsl similarity index 100% rename from shaders/tile_copy.fs.glsl rename to shaders/d3d9/tile_copy.fs.glsl diff --git a/shaders/tile_copy.vs.glsl b/shaders/d3d9/tile_copy.vs.glsl similarity index 100% rename from shaders/tile_copy.vs.glsl rename to shaders/d3d9/tile_copy.vs.glsl diff --git a/shaders/fill.inc.glsl b/shaders/fill.inc.glsl deleted file mode 100644 index c22125ae..00000000 --- a/shaders/fill.inc.glsl +++ /dev/null @@ -1,27 +0,0 @@ -// pathfinder/shaders/fill.inc.glsl -// -// Copyright © 2020 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -vec4 computeCoverage(vec2 from, vec2 to, sampler2D areaLUT) { - // Determine winding, and sort into a consistent order so we only need to find one root below. - vec2 left = from.x < to.x ? from : to, right = from.x < to.x ? to : from; - - // Shoot a vertical ray toward the curve. - vec2 window = clamp(vec2(from.x, to.x), -0.5, 0.5); - float offset = mix(window.x, window.y, 0.5) - left.x; - float t = offset / (right.x - left.x); - - // Compute position and derivative to form a line approximation. - float y = mix(left.y, right.y, t); - float d = (right.y - left.y) / (right.x - left.x); - - // Look up area under that line, and scale horizontally to the window size. - float dX = window.x - window.y; - return texture(areaLUT, vec2(y + 8.0, abs(d * dX)) / 16.0) * dX; -} diff --git a/shaders/tile.vs.glsl b/shaders/tile.vs.glsl deleted file mode 100644 index 3366e129..00000000 --- a/shaders/tile.vs.glsl +++ /dev/null @@ -1,56 +0,0 @@ -#version 330 - -// pathfinder/shaders/tile.vs.glsl -// -// Copyright © 2020 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -precision highp float; - -#ifdef GL_ES -precision highp sampler2D; -#endif - -uniform mat4 uTransform; -uniform vec2 uTileSize; -uniform sampler2D uTextureMetadata; -uniform ivec2 uTextureMetadataSize; - -in ivec2 aTileOffset; -in ivec2 aTileOrigin; -in uvec2 aMaskTexCoord0; -in ivec2 aMaskBackdrop; -in int aColor; -in int aTileCtrl; - -out vec3 vMaskTexCoord0; -out vec2 vColorTexCoord0; -out vec4 vBaseColor; -out float vTileCtrl; - -void main() { - vec2 tileOrigin = vec2(aTileOrigin), tileOffset = vec2(aTileOffset); - vec2 position = (tileOrigin + tileOffset) * uTileSize; - - vec2 maskTexCoord0 = (vec2(aMaskTexCoord0) + tileOffset) * uTileSize; - - vec2 textureMetadataScale = vec2(1.0) / vec2(uTextureMetadataSize); - vec2 metadataEntryCoord = vec2(aColor % 128 * 4, aColor / 128); - vec2 colorTexMatrix0Coord = (metadataEntryCoord + vec2(0.5, 0.5)) * textureMetadataScale; - vec2 colorTexOffsetsCoord = (metadataEntryCoord + vec2(1.5, 0.5)) * textureMetadataScale; - vec2 baseColorCoord = (metadataEntryCoord + vec2(2.5, 0.5)) * textureMetadataScale; - vec4 colorTexMatrix0 = texture(uTextureMetadata, colorTexMatrix0Coord); - vec4 colorTexOffsets = texture(uTextureMetadata, colorTexOffsetsCoord); - vec4 baseColor = texture(uTextureMetadata, baseColorCoord); - - vColorTexCoord0 = mat2(colorTexMatrix0) * position + colorTexOffsets.xy; - vMaskTexCoord0 = vec3(maskTexCoord0, float(aMaskBackdrop.x)); - vBaseColor = baseColor; - vTileCtrl = float(aTileCtrl); - gl_Position = uTransform * vec4(position, 0.0, 1.0); -} diff --git a/shaders/tile.fs.glsl b/shaders/tile_fragment.inc.glsl similarity index 93% rename from shaders/tile.fs.glsl rename to shaders/tile_fragment.inc.glsl index 487fcb5c..a03a13d2 100644 --- a/shaders/tile.fs.glsl +++ b/shaders/tile_fragment.inc.glsl @@ -1,6 +1,4 @@ -#version 330 - -// pathfinder/shaders/tile.fs.glsl +// pathfinder/shaders/tile_fragment.inc.glsl // // Copyright © 2020 The Pathfinder Project Developers. // @@ -31,14 +29,6 @@ // + + // Color UV 0 Color UV 1 -#extension GL_GOOGLE_include_directive : enable - -precision highp float; - -#ifdef GL_ES -precision highp sampler2D; -#endif - #define EPSILON 0.00001 #define FRAC_6_PI 1.9098593171027443 @@ -81,25 +71,6 @@ precision highp sampler2D; #define COMBINER_CTRL_COLOR_COMBINE_SHIFT 6 #define COMBINER_CTRL_COMPOSITE_SHIFT 8 -uniform sampler2D uColorTexture0; -uniform sampler2D uMaskTexture0; -uniform sampler2D uDestTexture; -uniform sampler2D uGammaLUT; -uniform vec2 uColorTextureSize0; -uniform vec2 uMaskTextureSize0; -uniform vec4 uFilterParams0; -uniform vec4 uFilterParams1; -uniform vec4 uFilterParams2; -uniform vec2 uFramebufferSize; -uniform int uCtrl; - -in vec3 vMaskTexCoord0; -in vec2 vColorTexCoord0; -in vec4 vBaseColor; -in float vTileCtrl; - -out vec4 oFragColor; - // Color sampling vec4 sampleColor(sampler2D colorTexture, vec2 colorTexCoord) { @@ -565,27 +536,42 @@ float sampleMask(float maskAlpha, // Main function -void calculateColor(int tileCtrl, int ctrl) { +vec4 calculateColor(vec2 fragCoord, + sampler2D colorTexture0, + sampler2D maskTexture0, + sampler2D destTexture, + sampler2D gammaLUT, + vec2 colorTextureSize0, + vec2 maskTextureSize0, + vec4 filterParams0, + vec4 filterParams1, + vec4 filterParams2, + vec2 framebufferSize, + int ctrl, + vec3 maskTexCoord0, + vec2 colorTexCoord0, + vec4 baseColor, + int tileCtrl) { // Sample mask. int maskCtrl0 = (tileCtrl >> TILE_CTRL_MASK_0_SHIFT) & TILE_CTRL_MASK_MASK; float maskAlpha = 1.0; - maskAlpha = sampleMask(maskAlpha, uMaskTexture0, uMaskTextureSize0, vMaskTexCoord0, maskCtrl0); + maskAlpha = sampleMask(maskAlpha, maskTexture0, maskTextureSize0, maskTexCoord0, maskCtrl0); // Sample color. - vec4 color = vBaseColor; + vec4 color = baseColor; int color0Combine = (ctrl >> COMBINER_CTRL_COLOR_COMBINE_SHIFT) & COMBINER_CTRL_COLOR_COMBINE_MASK; if (color0Combine != 0) { int color0Filter = (ctrl >> COMBINER_CTRL_COLOR_FILTER_SHIFT) & COMBINER_CTRL_FILTER_MASK; - vec4 color0 = filterColor(vColorTexCoord0, - uColorTexture0, - uGammaLUT, - uColorTextureSize0, - gl_FragCoord.xy, - uFramebufferSize, - uFilterParams0, - uFilterParams1, - uFilterParams2, + vec4 color0 = filterColor(colorTexCoord0, + colorTexture0, + gammaLUT, + colorTextureSize0, + fragCoord, + framebufferSize, + filterParams0, + filterParams1, + filterParams2, color0Filter); color = combineColor0(color, color0, color0Combine); } @@ -595,17 +581,9 @@ void calculateColor(int tileCtrl, int ctrl) { // Apply composite. int compositeOp = (ctrl >> COMBINER_CTRL_COMPOSITE_SHIFT) & COMBINER_CTRL_COMPOSITE_MASK; - color = composite(color, uDestTexture, uFramebufferSize, gl_FragCoord.xy, compositeOp); + color = composite(color, destTexture, framebufferSize, fragCoord, compositeOp); // Premultiply alpha. color.rgb *= color.a; - oFragColor = color; -} - -// Entry point -// -// TODO(pcwalton): Generate this dynamically. - -void main() { - calculateColor(int(vTileCtrl), uCtrl); + return color; } diff --git a/shaders/tile_vertex.inc.glsl b/shaders/tile_vertex.inc.glsl new file mode 100644 index 00000000..c99778a4 --- /dev/null +++ b/shaders/tile_vertex.inc.glsl @@ -0,0 +1,40 @@ +// pathfinder/shaders/tile_vertex.inc.glsl +// +// Copyright © 2020 The Pathfinder Project Developers. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +vec4 fetchUnscaled(sampler2D srcTexture, vec2 scale, vec2 originCoord, int entry) { + return texture(srcTexture, (originCoord + vec2(0.5) + vec2(entry, 0)) * scale); +} + +void computeTileVaryings(vec2 position, + int colorEntry, + sampler2D textureMetadata, + ivec2 textureMetadataSize, + out vec2 outColorTexCoord0, + out vec4 outBaseColor, + out vec4 outFilterParams0, + out vec4 outFilterParams1, + out vec4 outFilterParams2, + out int outCtrl) { + vec2 metadataScale = vec2(1.0) / vec2(textureMetadataSize); + vec2 metadataEntryCoord = vec2(colorEntry % 128 * 8, colorEntry / 128); + vec4 colorTexMatrix0 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 0); + vec4 colorTexOffsets = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 1); + vec4 baseColor = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 2); + vec4 filterParams0 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 3); + vec4 filterParams1 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 4); + vec4 filterParams2 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 5); + vec4 extra = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 6); + outColorTexCoord0 = mat2(colorTexMatrix0) * position + colorTexOffsets.xy; + outBaseColor = baseColor; + outFilterParams0 = filterParams0; + outFilterParams1 = filterParams1; + outFilterParams2 = filterParams2; + outCtrl = int(extra.x); +}