twitchapon-anim

Basic Twitchapon Receiver/Visuals
git clone git://bsandro.tech/twitchapon-anim
Log | Files | Refs | README | LICENSE

shader.go (3100B)


      1 // Copyright 2020 The Ebiten Authors
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //     http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 // +build darwin
     16 
     17 package metal
     18 
     19 import (
     20 	"fmt"
     21 
     22 	"github.com/hajimehoshi/ebiten/v2/internal/driver"
     23 	"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/metal/mtl"
     24 	"github.com/hajimehoshi/ebiten/v2/internal/shaderir"
     25 	"github.com/hajimehoshi/ebiten/v2/internal/shaderir/metal"
     26 )
     27 
     28 type Shader struct {
     29 	id driver.ShaderID
     30 
     31 	ir   *shaderir.Program
     32 	fs   mtl.Function
     33 	vs   mtl.Function
     34 	rpss map[driver.CompositeMode]mtl.RenderPipelineState
     35 }
     36 
     37 func newShader(device mtl.Device, id driver.ShaderID, program *shaderir.Program) (*Shader, error) {
     38 	s := &Shader{
     39 		id:   id,
     40 		ir:   program,
     41 		rpss: map[driver.CompositeMode]mtl.RenderPipelineState{},
     42 	}
     43 	if err := s.init(device); err != nil {
     44 		return nil, err
     45 	}
     46 	return s, nil
     47 }
     48 
     49 func (s *Shader) ID() driver.ShaderID {
     50 	return s.id
     51 }
     52 
     53 func (s *Shader) Dispose() {
     54 	for _, rps := range s.rpss {
     55 		rps.Release()
     56 	}
     57 	s.vs.Release()
     58 	s.fs.Release()
     59 }
     60 
     61 func (s *Shader) init(device mtl.Device) error {
     62 	const (
     63 		v = "Vertex"
     64 		f = "Fragment"
     65 	)
     66 
     67 	src := metal.Compile(s.ir, v, f)
     68 	lib, err := device.MakeLibrary(src, mtl.CompileOptions{})
     69 	if err != nil {
     70 		return fmt.Errorf("metal: device.MakeLibrary failed: %v, source: %s", err, src)
     71 	}
     72 	vs, err := lib.MakeFunction(v)
     73 	if err != nil {
     74 		return fmt.Errorf("metal: lib.MakeFunction for vertex failed: %v, source: %s", err, src)
     75 	}
     76 	fs, err := lib.MakeFunction(f)
     77 	if err != nil {
     78 		return fmt.Errorf("metal: lib.MakeFunction for fragment failed: %v, source: %s", err, src)
     79 	}
     80 	s.fs = fs
     81 	s.vs = vs
     82 	return nil
     83 }
     84 
     85 func (s *Shader) RenderPipelineState(device mtl.Device, c driver.CompositeMode) (mtl.RenderPipelineState, error) {
     86 	if rps, ok := s.rpss[c]; ok {
     87 		return rps, nil
     88 	}
     89 
     90 	rpld := mtl.RenderPipelineDescriptor{
     91 		VertexFunction:   s.vs,
     92 		FragmentFunction: s.fs,
     93 	}
     94 
     95 	// TODO: For the precise pixel format, whether the render target is the screen or not must be considered.
     96 	rpld.ColorAttachments[0].PixelFormat = mtl.PixelFormatRGBA8UNorm
     97 	rpld.ColorAttachments[0].BlendingEnabled = true
     98 
     99 	src, dst := c.Operations()
    100 	rpld.ColorAttachments[0].DestinationAlphaBlendFactor = operationToBlendFactor(dst)
    101 	rpld.ColorAttachments[0].DestinationRGBBlendFactor = operationToBlendFactor(dst)
    102 	rpld.ColorAttachments[0].SourceAlphaBlendFactor = operationToBlendFactor(src)
    103 	rpld.ColorAttachments[0].SourceRGBBlendFactor = operationToBlendFactor(src)
    104 
    105 	rps, err := device.MakeRenderPipelineState(rpld)
    106 	if err != nil {
    107 		return mtl.RenderPipelineState{}, err
    108 	}
    109 
    110 	s.rpss[c] = rps
    111 	return rps, nil
    112 }