Corentin Wallez | 4a9ef4e | 2018-07-18 11:40:26 +0200 | [diff] [blame] | 1 | // Copyright 2017 The Dawn Authors |
Corentin Wallez | b085eec | 2017-07-14 14:04:52 -0400 | [diff] [blame] | 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 | |
Corentin Wallez | d37523f | 2018-07-24 13:53:51 +0200 | [diff] [blame] | 15 | #include "dawn_native/opengl/RenderPipelineGL.h" |
Corentin Wallez | b085eec | 2017-07-14 14:04:52 -0400 | [diff] [blame] | 16 | |
Yan, Shaobo | a492427 | 2018-12-10 19:47:22 +0000 | [diff] [blame] | 17 | #include "dawn_native/opengl/DeviceGL.h" |
Corentin Wallez | d37523f | 2018-07-24 13:53:51 +0200 | [diff] [blame] | 18 | #include "dawn_native/opengl/Forward.h" |
Corentin Wallez | d37523f | 2018-07-24 13:53:51 +0200 | [diff] [blame] | 19 | #include "dawn_native/opengl/PersistentPipelineStateGL.h" |
Yunchao He | 6e30884 | 2019-01-04 09:53:50 +0000 | [diff] [blame] | 20 | #include "dawn_native/opengl/UtilsGL.h" |
Corentin Wallez | b085eec | 2017-07-14 14:04:52 -0400 | [diff] [blame] | 21 | |
Corentin Wallez | 49a65d0 | 2018-07-24 16:45:45 +0200 | [diff] [blame] | 22 | namespace dawn_native { namespace opengl { |
Corentin Wallez | b085eec | 2017-07-14 14:04:52 -0400 | [diff] [blame] | 23 | |
Austin Eng | d81fd82 | 2017-07-24 14:40:06 -0400 | [diff] [blame] | 24 | namespace { |
Yunchao He | 889d743 | 2019-03-27 18:08:50 +0000 | [diff] [blame] | 25 | |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 26 | GLenum GLPrimitiveTopology(wgpu::PrimitiveTopology primitiveTopology) { |
Austin Eng | d81fd82 | 2017-07-24 14:40:06 -0400 | [diff] [blame] | 27 | switch (primitiveTopology) { |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 28 | case wgpu::PrimitiveTopology::PointList: |
Austin Eng | d81fd82 | 2017-07-24 14:40:06 -0400 | [diff] [blame] | 29 | return GL_POINTS; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 30 | case wgpu::PrimitiveTopology::LineList: |
Austin Eng | d81fd82 | 2017-07-24 14:40:06 -0400 | [diff] [blame] | 31 | return GL_LINES; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 32 | case wgpu::PrimitiveTopology::LineStrip: |
Austin Eng | d81fd82 | 2017-07-24 14:40:06 -0400 | [diff] [blame] | 33 | return GL_LINE_STRIP; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 34 | case wgpu::PrimitiveTopology::TriangleList: |
Austin Eng | d81fd82 | 2017-07-24 14:40:06 -0400 | [diff] [blame] | 35 | return GL_TRIANGLES; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 36 | case wgpu::PrimitiveTopology::TriangleStrip: |
Austin Eng | d81fd82 | 2017-07-24 14:40:06 -0400 | [diff] [blame] | 37 | return GL_TRIANGLE_STRIP; |
Austin Eng | d81fd82 | 2017-07-24 14:40:06 -0400 | [diff] [blame] | 38 | } |
Ben Clayton | 999cc24 | 2021-09-23 17:34:53 +0000 | [diff] [blame] | 39 | UNREACHABLE(); |
Austin Eng | d81fd82 | 2017-07-24 14:40:06 -0400 | [diff] [blame] | 40 | } |
Yunchao He | 92700bf | 2018-12-27 06:32:31 +0000 | [diff] [blame] | 41 | |
Yunchao He | d2631f8 | 2019-07-06 00:11:10 +0000 | [diff] [blame] | 42 | void ApplyFrontFaceAndCulling(const OpenGLFunctions& gl, |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 43 | wgpu::FrontFace face, |
| 44 | wgpu::CullMode mode) { |
Corentin Wallez | 7268e7d | 2020-08-18 12:30:06 +0000 | [diff] [blame] | 45 | // Note that we invert winding direction in OpenGL. Because Y axis is up in OpenGL, |
| 46 | // which is different from WebGPU and other backends (Y axis is down). |
| 47 | GLenum direction = (face == wgpu::FrontFace::CCW) ? GL_CW : GL_CCW; |
| 48 | gl.FrontFace(direction); |
| 49 | |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 50 | if (mode == wgpu::CullMode::None) { |
Yunchao He | d2631f8 | 2019-07-06 00:11:10 +0000 | [diff] [blame] | 51 | gl.Disable(GL_CULL_FACE); |
| 52 | } else { |
| 53 | gl.Enable(GL_CULL_FACE); |
Yunchao He | d2631f8 | 2019-07-06 00:11:10 +0000 | [diff] [blame] | 54 | |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 55 | GLenum cullMode = (mode == wgpu::CullMode::Front) ? GL_FRONT : GL_BACK; |
Yunchao He | d2631f8 | 2019-07-06 00:11:10 +0000 | [diff] [blame] | 56 | gl.CullFace(cullMode); |
| 57 | } |
| 58 | } |
| 59 | |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 60 | GLenum GLBlendFactor(wgpu::BlendFactor factor, bool alpha) { |
Yunchao He | 92700bf | 2018-12-27 06:32:31 +0000 | [diff] [blame] | 61 | switch (factor) { |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 62 | case wgpu::BlendFactor::Zero: |
Yunchao He | 92700bf | 2018-12-27 06:32:31 +0000 | [diff] [blame] | 63 | return GL_ZERO; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 64 | case wgpu::BlendFactor::One: |
Yunchao He | 92700bf | 2018-12-27 06:32:31 +0000 | [diff] [blame] | 65 | return GL_ONE; |
Brandon Jones | 22b923c | 2021-04-15 18:34:29 +0000 | [diff] [blame] | 66 | case wgpu::BlendFactor::Src: |
Yunchao He | 92700bf | 2018-12-27 06:32:31 +0000 | [diff] [blame] | 67 | return GL_SRC_COLOR; |
Brandon Jones | 22b923c | 2021-04-15 18:34:29 +0000 | [diff] [blame] | 68 | case wgpu::BlendFactor::OneMinusSrc: |
Yunchao He | 92700bf | 2018-12-27 06:32:31 +0000 | [diff] [blame] | 69 | return GL_ONE_MINUS_SRC_COLOR; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 70 | case wgpu::BlendFactor::SrcAlpha: |
Yunchao He | 92700bf | 2018-12-27 06:32:31 +0000 | [diff] [blame] | 71 | return GL_SRC_ALPHA; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 72 | case wgpu::BlendFactor::OneMinusSrcAlpha: |
Yunchao He | 92700bf | 2018-12-27 06:32:31 +0000 | [diff] [blame] | 73 | return GL_ONE_MINUS_SRC_ALPHA; |
Brandon Jones | 22b923c | 2021-04-15 18:34:29 +0000 | [diff] [blame] | 74 | case wgpu::BlendFactor::Dst: |
Yunchao He | 92700bf | 2018-12-27 06:32:31 +0000 | [diff] [blame] | 75 | return GL_DST_COLOR; |
Brandon Jones | 22b923c | 2021-04-15 18:34:29 +0000 | [diff] [blame] | 76 | case wgpu::BlendFactor::OneMinusDst: |
Yunchao He | 92700bf | 2018-12-27 06:32:31 +0000 | [diff] [blame] | 77 | return GL_ONE_MINUS_DST_COLOR; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 78 | case wgpu::BlendFactor::DstAlpha: |
Yunchao He | 92700bf | 2018-12-27 06:32:31 +0000 | [diff] [blame] | 79 | return GL_DST_ALPHA; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 80 | case wgpu::BlendFactor::OneMinusDstAlpha: |
Yunchao He | 92700bf | 2018-12-27 06:32:31 +0000 | [diff] [blame] | 81 | return GL_ONE_MINUS_DST_ALPHA; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 82 | case wgpu::BlendFactor::SrcAlphaSaturated: |
Yunchao He | 92700bf | 2018-12-27 06:32:31 +0000 | [diff] [blame] | 83 | return GL_SRC_ALPHA_SATURATE; |
Brandon Jones | 22b923c | 2021-04-15 18:34:29 +0000 | [diff] [blame] | 84 | case wgpu::BlendFactor::Constant: |
Yunchao He | 92700bf | 2018-12-27 06:32:31 +0000 | [diff] [blame] | 85 | return alpha ? GL_CONSTANT_ALPHA : GL_CONSTANT_COLOR; |
Brandon Jones | 22b923c | 2021-04-15 18:34:29 +0000 | [diff] [blame] | 86 | case wgpu::BlendFactor::OneMinusConstant: |
Yunchao He | 92700bf | 2018-12-27 06:32:31 +0000 | [diff] [blame] | 87 | return alpha ? GL_ONE_MINUS_CONSTANT_ALPHA : GL_ONE_MINUS_CONSTANT_COLOR; |
Yunchao He | 92700bf | 2018-12-27 06:32:31 +0000 | [diff] [blame] | 88 | } |
Ben Clayton | 999cc24 | 2021-09-23 17:34:53 +0000 | [diff] [blame] | 89 | UNREACHABLE(); |
Yunchao He | 92700bf | 2018-12-27 06:32:31 +0000 | [diff] [blame] | 90 | } |
| 91 | |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 92 | GLenum GLBlendMode(wgpu::BlendOperation operation) { |
Yunchao He | 92700bf | 2018-12-27 06:32:31 +0000 | [diff] [blame] | 93 | switch (operation) { |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 94 | case wgpu::BlendOperation::Add: |
Yunchao He | 92700bf | 2018-12-27 06:32:31 +0000 | [diff] [blame] | 95 | return GL_FUNC_ADD; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 96 | case wgpu::BlendOperation::Subtract: |
Yunchao He | 92700bf | 2018-12-27 06:32:31 +0000 | [diff] [blame] | 97 | return GL_FUNC_SUBTRACT; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 98 | case wgpu::BlendOperation::ReverseSubtract: |
Yunchao He | 92700bf | 2018-12-27 06:32:31 +0000 | [diff] [blame] | 99 | return GL_FUNC_REVERSE_SUBTRACT; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 100 | case wgpu::BlendOperation::Min: |
Yunchao He | 92700bf | 2018-12-27 06:32:31 +0000 | [diff] [blame] | 101 | return GL_MIN; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 102 | case wgpu::BlendOperation::Max: |
Yunchao He | 92700bf | 2018-12-27 06:32:31 +0000 | [diff] [blame] | 103 | return GL_MAX; |
Yunchao He | 92700bf | 2018-12-27 06:32:31 +0000 | [diff] [blame] | 104 | } |
Ben Clayton | 999cc24 | 2021-09-23 17:34:53 +0000 | [diff] [blame] | 105 | UNREACHABLE(); |
Yunchao He | 92700bf | 2018-12-27 06:32:31 +0000 | [diff] [blame] | 106 | } |
| 107 | |
Corentin Wallez | df69f24 | 2019-06-13 10:22:32 +0000 | [diff] [blame] | 108 | void ApplyColorState(const OpenGLFunctions& gl, |
Austin Eng | 7b7e098 | 2020-09-09 00:08:38 +0000 | [diff] [blame] | 109 | ColorAttachmentIndex attachment, |
Brandon Jones | 97da45c | 2021-03-22 22:17:26 +0000 | [diff] [blame] | 110 | const ColorTargetState* state) { |
Austin Eng | 7b7e098 | 2020-09-09 00:08:38 +0000 | [diff] [blame] | 111 | GLuint colorBuffer = static_cast<GLuint>(static_cast<uint8_t>(attachment)); |
Brandon Jones | 97da45c | 2021-03-22 22:17:26 +0000 | [diff] [blame] | 112 | if (state->blend != nullptr) { |
Stephen White | 0421841 | 2020-12-07 19:31:03 +0000 | [diff] [blame] | 113 | gl.Enablei(GL_BLEND, colorBuffer); |
Brandon Jones | 97da45c | 2021-03-22 22:17:26 +0000 | [diff] [blame] | 114 | gl.BlendEquationSeparatei(colorBuffer, GLBlendMode(state->blend->color.operation), |
| 115 | GLBlendMode(state->blend->alpha.operation)); |
Stephen White | 0421841 | 2020-12-07 19:31:03 +0000 | [diff] [blame] | 116 | gl.BlendFuncSeparatei(colorBuffer, |
Brandon Jones | 97da45c | 2021-03-22 22:17:26 +0000 | [diff] [blame] | 117 | GLBlendFactor(state->blend->color.srcFactor, false), |
| 118 | GLBlendFactor(state->blend->color.dstFactor, false), |
| 119 | GLBlendFactor(state->blend->alpha.srcFactor, true), |
| 120 | GLBlendFactor(state->blend->alpha.dstFactor, true)); |
Yunchao He | 92700bf | 2018-12-27 06:32:31 +0000 | [diff] [blame] | 121 | } else { |
Stephen White | 0421841 | 2020-12-07 19:31:03 +0000 | [diff] [blame] | 122 | gl.Disablei(GL_BLEND, colorBuffer); |
Yunchao He | 92700bf | 2018-12-27 06:32:31 +0000 | [diff] [blame] | 123 | } |
Brandon Jones | 97da45c | 2021-03-22 22:17:26 +0000 | [diff] [blame] | 124 | gl.ColorMaski(colorBuffer, state->writeMask & wgpu::ColorWriteMask::Red, |
| 125 | state->writeMask & wgpu::ColorWriteMask::Green, |
| 126 | state->writeMask & wgpu::ColorWriteMask::Blue, |
| 127 | state->writeMask & wgpu::ColorWriteMask::Alpha); |
Stephen White | 0421841 | 2020-12-07 19:31:03 +0000 | [diff] [blame] | 128 | } |
| 129 | |
Brandon Jones | 97da45c | 2021-03-22 22:17:26 +0000 | [diff] [blame] | 130 | void ApplyColorState(const OpenGLFunctions& gl, const ColorTargetState* state) { |
| 131 | if (state->blend != nullptr) { |
Stephen White | 0421841 | 2020-12-07 19:31:03 +0000 | [diff] [blame] | 132 | gl.Enable(GL_BLEND); |
Brandon Jones | 97da45c | 2021-03-22 22:17:26 +0000 | [diff] [blame] | 133 | gl.BlendEquationSeparate(GLBlendMode(state->blend->color.operation), |
| 134 | GLBlendMode(state->blend->alpha.operation)); |
| 135 | gl.BlendFuncSeparate(GLBlendFactor(state->blend->color.srcFactor, false), |
| 136 | GLBlendFactor(state->blend->color.dstFactor, false), |
| 137 | GLBlendFactor(state->blend->alpha.srcFactor, true), |
| 138 | GLBlendFactor(state->blend->alpha.dstFactor, true)); |
Stephen White | 0421841 | 2020-12-07 19:31:03 +0000 | [diff] [blame] | 139 | } else { |
| 140 | gl.Disable(GL_BLEND); |
| 141 | } |
Brandon Jones | 97da45c | 2021-03-22 22:17:26 +0000 | [diff] [blame] | 142 | gl.ColorMask(state->writeMask & wgpu::ColorWriteMask::Red, |
| 143 | state->writeMask & wgpu::ColorWriteMask::Green, |
| 144 | state->writeMask & wgpu::ColorWriteMask::Blue, |
| 145 | state->writeMask & wgpu::ColorWriteMask::Alpha); |
Stephen White | 0421841 | 2020-12-07 19:31:03 +0000 | [diff] [blame] | 146 | } |
| 147 | |
Corentin Wallez | da230e5 | 2021-08-23 10:10:11 +0000 | [diff] [blame] | 148 | bool Equal(const BlendComponent& lhs, const BlendComponent& rhs) { |
Stephen White | 0421841 | 2020-12-07 19:31:03 +0000 | [diff] [blame] | 149 | return lhs.operation == rhs.operation && lhs.srcFactor == rhs.srcFactor && |
| 150 | lhs.dstFactor == rhs.dstFactor; |
Yunchao He | 92700bf | 2018-12-27 06:32:31 +0000 | [diff] [blame] | 151 | } |
| 152 | |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 153 | GLuint OpenGLStencilOperation(wgpu::StencilOperation stencilOperation) { |
Yunchao He | ea56333 | 2019-01-04 04:28:37 +0000 | [diff] [blame] | 154 | switch (stencilOperation) { |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 155 | case wgpu::StencilOperation::Keep: |
Yunchao He | ea56333 | 2019-01-04 04:28:37 +0000 | [diff] [blame] | 156 | return GL_KEEP; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 157 | case wgpu::StencilOperation::Zero: |
Yunchao He | ea56333 | 2019-01-04 04:28:37 +0000 | [diff] [blame] | 158 | return GL_ZERO; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 159 | case wgpu::StencilOperation::Replace: |
Yunchao He | ea56333 | 2019-01-04 04:28:37 +0000 | [diff] [blame] | 160 | return GL_REPLACE; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 161 | case wgpu::StencilOperation::Invert: |
Yunchao He | ea56333 | 2019-01-04 04:28:37 +0000 | [diff] [blame] | 162 | return GL_INVERT; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 163 | case wgpu::StencilOperation::IncrementClamp: |
Yunchao He | ea56333 | 2019-01-04 04:28:37 +0000 | [diff] [blame] | 164 | return GL_INCR; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 165 | case wgpu::StencilOperation::DecrementClamp: |
Yunchao He | ea56333 | 2019-01-04 04:28:37 +0000 | [diff] [blame] | 166 | return GL_DECR; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 167 | case wgpu::StencilOperation::IncrementWrap: |
Yunchao He | ea56333 | 2019-01-04 04:28:37 +0000 | [diff] [blame] | 168 | return GL_INCR_WRAP; |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 169 | case wgpu::StencilOperation::DecrementWrap: |
Yunchao He | ea56333 | 2019-01-04 04:28:37 +0000 | [diff] [blame] | 170 | return GL_DECR_WRAP; |
Yunchao He | ea56333 | 2019-01-04 04:28:37 +0000 | [diff] [blame] | 171 | } |
Ben Clayton | 999cc24 | 2021-09-23 17:34:53 +0000 | [diff] [blame] | 172 | UNREACHABLE(); |
Yunchao He | ea56333 | 2019-01-04 04:28:37 +0000 | [diff] [blame] | 173 | } |
| 174 | |
Corentin Wallez | df69f24 | 2019-06-13 10:22:32 +0000 | [diff] [blame] | 175 | void ApplyDepthStencilState(const OpenGLFunctions& gl, |
Brandon Jones | 97da45c | 2021-03-22 22:17:26 +0000 | [diff] [blame] | 176 | const DepthStencilState* descriptor, |
Yunchao He | ea56333 | 2019-01-04 04:28:37 +0000 | [diff] [blame] | 177 | PersistentPipelineState* persistentPipelineState) { |
| 178 | // Depth writes only occur if depth is enabled |
Corentin Wallez | 1f6c8c4 | 2019-10-23 11:57:41 +0000 | [diff] [blame] | 179 | if (descriptor->depthCompare == wgpu::CompareFunction::Always && |
Yunchao He | ea56333 | 2019-01-04 04:28:37 +0000 | [diff] [blame] | 180 | !descriptor->depthWriteEnabled) { |
Corentin Wallez | df69f24 | 2019-06-13 10:22:32 +0000 | [diff] [blame] | 181 | gl.Disable(GL_DEPTH_TEST); |
Yunchao He | ea56333 | 2019-01-04 04:28:37 +0000 | [diff] [blame] | 182 | } else { |
Corentin Wallez | df69f24 | 2019-06-13 10:22:32 +0000 | [diff] [blame] | 183 | gl.Enable(GL_DEPTH_TEST); |
Yunchao He | ea56333 | 2019-01-04 04:28:37 +0000 | [diff] [blame] | 184 | } |
| 185 | |
| 186 | if (descriptor->depthWriteEnabled) { |
Corentin Wallez | df69f24 | 2019-06-13 10:22:32 +0000 | [diff] [blame] | 187 | gl.DepthMask(GL_TRUE); |
Yunchao He | ea56333 | 2019-01-04 04:28:37 +0000 | [diff] [blame] | 188 | } else { |
Corentin Wallez | df69f24 | 2019-06-13 10:22:32 +0000 | [diff] [blame] | 189 | gl.DepthMask(GL_FALSE); |
Yunchao He | ea56333 | 2019-01-04 04:28:37 +0000 | [diff] [blame] | 190 | } |
| 191 | |
Corentin Wallez | df69f24 | 2019-06-13 10:22:32 +0000 | [diff] [blame] | 192 | gl.DepthFunc(ToOpenGLCompareFunction(descriptor->depthCompare)); |
Yunchao He | ea56333 | 2019-01-04 04:28:37 +0000 | [diff] [blame] | 193 | |
| 194 | if (StencilTestEnabled(descriptor)) { |
Corentin Wallez | df69f24 | 2019-06-13 10:22:32 +0000 | [diff] [blame] | 195 | gl.Enable(GL_STENCIL_TEST); |
Yunchao He | ea56333 | 2019-01-04 04:28:37 +0000 | [diff] [blame] | 196 | } else { |
Corentin Wallez | df69f24 | 2019-06-13 10:22:32 +0000 | [diff] [blame] | 197 | gl.Disable(GL_STENCIL_TEST); |
Yunchao He | ea56333 | 2019-01-04 04:28:37 +0000 | [diff] [blame] | 198 | } |
| 199 | |
Yunchao He | baa3741 | 2019-01-30 21:11:43 +0000 | [diff] [blame] | 200 | GLenum backCompareFunction = ToOpenGLCompareFunction(descriptor->stencilBack.compare); |
| 201 | GLenum frontCompareFunction = ToOpenGLCompareFunction(descriptor->stencilFront.compare); |
Yunchao He | ea56333 | 2019-01-04 04:28:37 +0000 | [diff] [blame] | 202 | persistentPipelineState->SetStencilFuncsAndMask( |
Corentin Wallez | df69f24 | 2019-06-13 10:22:32 +0000 | [diff] [blame] | 203 | gl, backCompareFunction, frontCompareFunction, descriptor->stencilReadMask); |
Yunchao He | ea56333 | 2019-01-04 04:28:37 +0000 | [diff] [blame] | 204 | |
Corentin Wallez | df69f24 | 2019-06-13 10:22:32 +0000 | [diff] [blame] | 205 | gl.StencilOpSeparate(GL_BACK, OpenGLStencilOperation(descriptor->stencilBack.failOp), |
| 206 | OpenGLStencilOperation(descriptor->stencilBack.depthFailOp), |
| 207 | OpenGLStencilOperation(descriptor->stencilBack.passOp)); |
| 208 | gl.StencilOpSeparate(GL_FRONT, OpenGLStencilOperation(descriptor->stencilFront.failOp), |
| 209 | OpenGLStencilOperation(descriptor->stencilFront.depthFailOp), |
| 210 | OpenGLStencilOperation(descriptor->stencilFront.passOp)); |
Yunchao He | ea56333 | 2019-01-04 04:28:37 +0000 | [diff] [blame] | 211 | |
Corentin Wallez | df69f24 | 2019-06-13 10:22:32 +0000 | [diff] [blame] | 212 | gl.StencilMask(descriptor->stencilWriteMask); |
Yunchao He | ea56333 | 2019-01-04 04:28:37 +0000 | [diff] [blame] | 213 | } |
| 214 | |
| 215 | } // anonymous namespace |
Austin Eng | d81fd82 | 2017-07-24 14:40:06 -0400 | [diff] [blame] | 216 | |
Austin Eng | 8e95716 | 2021-08-03 19:07:29 +0000 | [diff] [blame] | 217 | // static |
Jiawei Shao | 3c0925b | 2021-09-29 00:49:01 +0000 | [diff] [blame] | 218 | Ref<RenderPipeline> RenderPipeline::CreateUninitialized( |
Austin Eng | 8e95716 | 2021-08-03 19:07:29 +0000 | [diff] [blame] | 219 | Device* device, |
| 220 | const RenderPipelineDescriptor* descriptor) { |
Jiawei Shao | 3c0925b | 2021-09-29 00:49:01 +0000 | [diff] [blame] | 221 | return AcquireRef(new RenderPipeline(device, descriptor)); |
Austin Eng | 8e95716 | 2021-08-03 19:07:29 +0000 | [diff] [blame] | 222 | } |
| 223 | |
Brandon Jones | 41c87d9 | 2021-05-21 05:01:38 +0000 | [diff] [blame] | 224 | RenderPipeline::RenderPipeline(Device* device, const RenderPipelineDescriptor* descriptor) |
Yan, Shaobo | a492427 | 2018-12-10 19:47:22 +0000 | [diff] [blame] | 225 | : RenderPipelineBase(device, descriptor), |
Yunchao He | 889d743 | 2019-03-27 18:08:50 +0000 | [diff] [blame] | 226 | mVertexArrayObject(0), |
Corentin Wallez | 7ee1610 | 2017-11-23 11:24:20 -0800 | [diff] [blame] | 227 | mGlPrimitiveTopology(GLPrimitiveTopology(GetPrimitiveTopology())) { |
Austin Eng | 8e95716 | 2021-08-03 19:07:29 +0000 | [diff] [blame] | 228 | } |
Corentin Wallez | 8e335a5 | 2018-08-27 23:12:56 +0200 | [diff] [blame] | 229 | |
Austin Eng | 8e95716 | 2021-08-03 19:07:29 +0000 | [diff] [blame] | 230 | MaybeError RenderPipeline::Initialize() { |
| 231 | DAWN_TRY( |
| 232 | InitializeBase(ToBackend(GetDevice())->gl, ToBackend(GetLayout()), GetAllStages())); |
Brandon Jones | f759264 | 2021-04-02 19:42:28 +0000 | [diff] [blame] | 233 | CreateVAOForVertexState(); |
Austin Eng | 8e95716 | 2021-08-03 19:07:29 +0000 | [diff] [blame] | 234 | return {}; |
Yunchao He | 889d743 | 2019-03-27 18:08:50 +0000 | [diff] [blame] | 235 | } |
| 236 | |
Loko Kung | 2c67af9 | 2021-11-11 00:39:22 +0000 | [diff] [blame] | 237 | RenderPipeline::~RenderPipeline() = default; |
| 238 | |
Loko Kung | e9c84c0 | 2021-11-11 01:39:52 +0000 | [diff] [blame] | 239 | void RenderPipeline::DestroyImpl() { |
Loko Kung | 6331f95 | 2021-12-01 18:54:40 +0000 | [diff] [blame] | 240 | RenderPipelineBase::DestroyImpl(); |
Corentin Wallez | df69f24 | 2019-06-13 10:22:32 +0000 | [diff] [blame] | 241 | const OpenGLFunctions& gl = ToBackend(GetDevice())->gl; |
| 242 | gl.DeleteVertexArrays(1, &mVertexArrayObject); |
| 243 | gl.BindVertexArray(0); |
Jiawei Shao | afe9138 | 2021-10-04 12:31:22 +0000 | [diff] [blame] | 244 | DeleteProgram(gl); |
Austin Eng | d81fd82 | 2017-07-24 14:40:06 -0400 | [diff] [blame] | 245 | } |
| 246 | |
| 247 | GLenum RenderPipeline::GetGLPrimitiveTopology() const { |
Corentin Wallez | 7ee1610 | 2017-11-23 11:24:20 -0800 | [diff] [blame] | 248 | return mGlPrimitiveTopology; |
Corentin Wallez | b085eec | 2017-07-14 14:04:52 -0400 | [diff] [blame] | 249 | } |
| 250 | |
Austin Eng | 4099f65 | 2020-09-17 19:07:00 +0000 | [diff] [blame] | 251 | ityp::bitset<VertexAttributeLocation, kMaxVertexAttributes> |
| 252 | RenderPipeline::GetAttributesUsingVertexBuffer(VertexBufferSlot slot) const { |
| 253 | ASSERT(!IsError()); |
| 254 | return mAttributesUsingVertexBuffer[slot]; |
| 255 | } |
| 256 | |
Brandon Jones | f759264 | 2021-04-02 19:42:28 +0000 | [diff] [blame] | 257 | void RenderPipeline::CreateVAOForVertexState() { |
Corentin Wallez | df69f24 | 2019-06-13 10:22:32 +0000 | [diff] [blame] | 258 | const OpenGLFunctions& gl = ToBackend(GetDevice())->gl; |
| 259 | |
| 260 | gl.GenVertexArrays(1, &mVertexArrayObject); |
| 261 | gl.BindVertexArray(mVertexArrayObject); |
| 262 | |
Austin Eng | 4099f65 | 2020-09-17 19:07:00 +0000 | [diff] [blame] | 263 | for (VertexAttributeLocation location : IterateBitSet(GetAttributeLocationsUsed())) { |
Yunchao He | 494552b | 2019-03-28 10:57:41 +0000 | [diff] [blame] | 264 | const auto& attribute = GetAttribute(location); |
Austin Eng | 4099f65 | 2020-09-17 19:07:00 +0000 | [diff] [blame] | 265 | GLuint glAttrib = static_cast<GLuint>(static_cast<uint8_t>(location)); |
| 266 | gl.EnableVertexAttribArray(glAttrib); |
Yunchao He | 889d743 | 2019-03-27 18:08:50 +0000 | [diff] [blame] | 267 | |
Austin Eng | 4099f65 | 2020-09-17 19:07:00 +0000 | [diff] [blame] | 268 | mAttributesUsingVertexBuffer[attribute.vertexBufferSlot][location] = true; |
Kai Ninomiya | ae1f25f | 2019-11-07 22:23:29 +0000 | [diff] [blame] | 269 | const VertexBufferInfo& vertexBuffer = GetVertexBuffer(attribute.vertexBufferSlot); |
Yunchao He | 889d743 | 2019-03-27 18:08:50 +0000 | [diff] [blame] | 270 | |
Kai Ninomiya | ae1f25f | 2019-11-07 22:23:29 +0000 | [diff] [blame] | 271 | if (vertexBuffer.arrayStride == 0) { |
Yunchao He | 889d743 | 2019-03-27 18:08:50 +0000 | [diff] [blame] | 272 | // Emulate a stride of zero (constant vertex attribute) by |
| 273 | // setting the attribute instance divisor to a huge number. |
Austin Eng | 4099f65 | 2020-09-17 19:07:00 +0000 | [diff] [blame] | 274 | gl.VertexAttribDivisor(glAttrib, 0xffffffff); |
Yunchao He | 889d743 | 2019-03-27 18:08:50 +0000 | [diff] [blame] | 275 | } else { |
Kai Ninomiya | ae1f25f | 2019-11-07 22:23:29 +0000 | [diff] [blame] | 276 | switch (vertexBuffer.stepMode) { |
Corentin Wallez | ff6c9ca6 | 2021-07-25 18:40:19 +0000 | [diff] [blame] | 277 | case wgpu::VertexStepMode::Vertex: |
Yunchao He | 889d743 | 2019-03-27 18:08:50 +0000 | [diff] [blame] | 278 | break; |
Corentin Wallez | ff6c9ca6 | 2021-07-25 18:40:19 +0000 | [diff] [blame] | 279 | case wgpu::VertexStepMode::Instance: |
Austin Eng | 4099f65 | 2020-09-17 19:07:00 +0000 | [diff] [blame] | 280 | gl.VertexAttribDivisor(glAttrib, 1); |
Yunchao He | 889d743 | 2019-03-27 18:08:50 +0000 | [diff] [blame] | 281 | break; |
Yunchao He | 889d743 | 2019-03-27 18:08:50 +0000 | [diff] [blame] | 282 | } |
| 283 | } |
| 284 | } |
| 285 | } |
| 286 | |
Corentin Wallez | c7807ab | 2017-11-24 14:16:15 -0500 | [diff] [blame] | 287 | void RenderPipeline::ApplyNow(PersistentPipelineState& persistentPipelineState) { |
Corentin Wallez | df69f24 | 2019-06-13 10:22:32 +0000 | [diff] [blame] | 288 | const OpenGLFunctions& gl = ToBackend(GetDevice())->gl; |
| 289 | PipelineGL::ApplyNow(gl); |
Corentin Wallez | b085eec | 2017-07-14 14:04:52 -0400 | [diff] [blame] | 290 | |
Yunchao He | 889d743 | 2019-03-27 18:08:50 +0000 | [diff] [blame] | 291 | ASSERT(mVertexArrayObject); |
Corentin Wallez | df69f24 | 2019-06-13 10:22:32 +0000 | [diff] [blame] | 292 | gl.BindVertexArray(mVertexArrayObject); |
Corentin Wallez | b085eec | 2017-07-14 14:04:52 -0400 | [diff] [blame] | 293 | |
Yunchao He | d2631f8 | 2019-07-06 00:11:10 +0000 | [diff] [blame] | 294 | ApplyFrontFaceAndCulling(gl, GetFrontFace(), GetCullMode()); |
| 295 | |
Brandon Jones | 97da45c | 2021-03-22 22:17:26 +0000 | [diff] [blame] | 296 | ApplyDepthStencilState(gl, GetDepthStencilState(), &persistentPipelineState); |
Austin Eng | 8dc3bd1 | 2017-08-01 18:22:57 -0400 | [diff] [blame] | 297 | |
Corentin Wallez | c7ae7a0 | 2020-07-23 16:26:16 +0000 | [diff] [blame] | 298 | gl.SampleMaski(0, GetSampleMask()); |
Tomek Ponitka | ab04da4 | 2020-07-29 11:44:41 +0000 | [diff] [blame] | 299 | if (IsAlphaToCoverageEnabled()) { |
| 300 | gl.Enable(GL_SAMPLE_ALPHA_TO_COVERAGE); |
| 301 | } else { |
| 302 | gl.Disable(GL_SAMPLE_ALPHA_TO_COVERAGE); |
| 303 | } |
Corentin Wallez | c7ae7a0 | 2020-07-23 16:26:16 +0000 | [diff] [blame] | 304 | |
Enrico Galli | db2c2dd | 2020-10-06 08:12:29 +0000 | [diff] [blame] | 305 | if (IsDepthBiasEnabled()) { |
| 306 | gl.Enable(GL_POLYGON_OFFSET_FILL); |
| 307 | float depthBias = GetDepthBias(); |
| 308 | float slopeScale = GetDepthBiasSlopeScale(); |
| 309 | if (gl.PolygonOffsetClamp != nullptr) { |
| 310 | gl.PolygonOffsetClamp(slopeScale, depthBias, GetDepthBiasClamp()); |
| 311 | } else { |
| 312 | gl.PolygonOffset(slopeScale, depthBias); |
| 313 | } |
| 314 | } else { |
| 315 | gl.Disable(GL_POLYGON_OFFSET_FILL); |
| 316 | } |
| 317 | |
Stephen White | 0421841 | 2020-12-07 19:31:03 +0000 | [diff] [blame] | 318 | if (!GetDevice()->IsToggleEnabled(Toggle::DisableIndexedDrawBuffers)) { |
| 319 | for (ColorAttachmentIndex attachmentSlot : IterateBitSet(GetColorAttachmentsMask())) { |
Brandon Jones | 97da45c | 2021-03-22 22:17:26 +0000 | [diff] [blame] | 320 | ApplyColorState(gl, attachmentSlot, GetColorTargetState(attachmentSlot)); |
Stephen White | 0421841 | 2020-12-07 19:31:03 +0000 | [diff] [blame] | 321 | } |
| 322 | } else { |
Brandon Jones | 97da45c | 2021-03-22 22:17:26 +0000 | [diff] [blame] | 323 | const ColorTargetState* prevDescriptor = nullptr; |
Stephen White | 0421841 | 2020-12-07 19:31:03 +0000 | [diff] [blame] | 324 | for (ColorAttachmentIndex attachmentSlot : IterateBitSet(GetColorAttachmentsMask())) { |
Brandon Jones | 97da45c | 2021-03-22 22:17:26 +0000 | [diff] [blame] | 325 | const ColorTargetState* descriptor = GetColorTargetState(attachmentSlot); |
Stephen White | 0421841 | 2020-12-07 19:31:03 +0000 | [diff] [blame] | 326 | if (!prevDescriptor) { |
| 327 | ApplyColorState(gl, descriptor); |
| 328 | prevDescriptor = descriptor; |
Brandon Jones | 97da45c | 2021-03-22 22:17:26 +0000 | [diff] [blame] | 329 | } else if ((descriptor->blend == nullptr) != (prevDescriptor->blend == nullptr)) { |
| 330 | // TODO(crbug.com/dawn/582): GLES < 3.2 does not support different blend states |
| 331 | // per color target. Add validation to prevent this as it is not. |
Stephen White | 0421841 | 2020-12-07 19:31:03 +0000 | [diff] [blame] | 332 | ASSERT(false); |
Brandon Jones | 97da45c | 2021-03-22 22:17:26 +0000 | [diff] [blame] | 333 | } else if (descriptor->blend != nullptr) { |
| 334 | if (!Equal(descriptor->blend->alpha, prevDescriptor->blend->alpha) || |
| 335 | !Equal(descriptor->blend->color, prevDescriptor->blend->color) || |
| 336 | descriptor->writeMask != prevDescriptor->writeMask) { |
| 337 | // TODO(crbug.com/dawn/582) |
| 338 | ASSERT(false); |
| 339 | } |
Stephen White | 0421841 | 2020-12-07 19:31:03 +0000 | [diff] [blame] | 340 | } |
| 341 | } |
Austin Eng | 8dc3bd1 | 2017-08-01 18:22:57 -0400 | [diff] [blame] | 342 | } |
Corentin Wallez | b085eec | 2017-07-14 14:04:52 -0400 | [diff] [blame] | 343 | } |
| 344 | |
Corentin Wallez | 49a65d0 | 2018-07-24 16:45:45 +0200 | [diff] [blame] | 345 | }} // namespace dawn_native::opengl |