1 /*
   2  * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 #include <simd/simd.h>
  27 #include <metal_stdlib>
  28 #include "common.h"
  29 
  30 using namespace metal;
  31 
  32 struct VertexInput {
  33     float3 position [[attribute(VertexAttributePosition)]];
  34 };
  35 
  36 struct TxtVertexInput {
  37     float3 position [[attribute(VertexAttributePosition)]];
  38     float2 texCoords [[attribute(VertexAttributeTexPos)]];
  39 };
  40 
  41 struct ColShaderInOut {
  42     float4 position [[position]];
  43     half4  color;
  44 };
  45 
  46 struct TxtShaderInOut {
  47     float4 position [[position]];
  48     float2 texCoords;
  49 };
  50 
  51 struct GradShaderInOut {
  52     float4 position [[position]];
  53 };
  54 
  55 vertex ColShaderInOut vert_col(VertexInput in [[stage_in]],
  56            constant FrameUniforms& uniforms [[buffer(FrameUniformBuffer)]],
  57        constant TransformMatrix& transform [[buffer(MatrixBuffer)]]) {
  58     ColShaderInOut out;
  59     float4 pos4 = float4(in.position, 1.0);
  60     out.position = transform.transformMatrix*pos4;
  61     out.color = half4(uniforms.color.r, uniforms.color.g, uniforms.color.b, uniforms.color.a);
  62     return out;
  63 }
  64 
  65 vertex GradShaderInOut vert_grad(VertexInput in [[stage_in]], constant TransformMatrix& transform [[buffer(MatrixBuffer)]]) {
  66     GradShaderInOut out;
  67     float4 pos4 = float4(in.position, 1.0);
  68     out.position = transform.transformMatrix*pos4;
  69     return out;
  70 }
  71 
  72 vertex TxtShaderInOut vert_txt(TxtVertexInput in [[stage_in]], constant TransformMatrix& transform [[buffer(MatrixBuffer)]]) {
  73     TxtShaderInOut out;
  74     float4 pos4 = float4(in.position, 1.0);
  75     out.position = transform.transformMatrix*pos4;
  76     out.texCoords = in.texCoords;
  77     return out;
  78 }
  79 
  80 fragment half4 frag_col(ColShaderInOut in [[stage_in]]) {
  81     return in.color;
  82 }
  83 
  84 fragment half4 frag_txt(
  85         TxtShaderInOut vert [[stage_in]],
  86         texture2d<float, access::sample> renderTexture [[texture(0)]]
  87         )
  88 {
  89     constexpr sampler textureSampler (mag_filter::linear,
  90                                   min_filter::linear);
  91     float4 pixelColor = renderTexture.sample(textureSampler, vert.texCoords);
  92     return half4(pixelColor.r, pixelColor.g, pixelColor.b , pixelColor.a);
  93 }
  94 
  95 fragment half4 frag_grad(GradShaderInOut in [[stage_in]],
  96                          constant GradFrameUniforms& uniforms [[buffer(0)]]) {
  97     float3 v = float3(in.position.x, in.position.y, 1);
  98     float  a = (dot(v,uniforms.params)-0.25)*2.0;
  99     float4 c = mix(uniforms.color1, uniforms.color2, a);
 100     return half4(c);
 101 }