blob: bc8c2c6155acceb250da0af624596a777763efb3 [file] [log] [blame]
Corentin Wallez4a9ef4e2018-07-18 11:40:26 +02001// Copyright 2017 The Dawn Authors
Corentin Wallezb085eec2017-07-14 14:04:52 -04002//
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 Wallezd37523f2018-07-24 13:53:51 +020015#include "dawn_native/opengl/RenderPipelineGL.h"
Corentin Wallezb085eec2017-07-14 14:04:52 -040016
Yan, Shaoboa4924272018-12-10 19:47:22 +000017#include "dawn_native/opengl/DeviceGL.h"
Corentin Wallezd37523f2018-07-24 13:53:51 +020018#include "dawn_native/opengl/Forward.h"
Corentin Wallezd37523f2018-07-24 13:53:51 +020019#include "dawn_native/opengl/PersistentPipelineStateGL.h"
Yunchao He6e308842019-01-04 09:53:50 +000020#include "dawn_native/opengl/UtilsGL.h"
Corentin Wallezb085eec2017-07-14 14:04:52 -040021
Corentin Wallez49a65d02018-07-24 16:45:45 +020022namespace dawn_native { namespace opengl {
Corentin Wallezb085eec2017-07-14 14:04:52 -040023
Austin Engd81fd822017-07-24 14:40:06 -040024 namespace {
Yunchao He889d7432019-03-27 18:08:50 +000025
Corentin Wallez1f6c8c42019-10-23 11:57:41 +000026 GLenum GLPrimitiveTopology(wgpu::PrimitiveTopology primitiveTopology) {
Austin Engd81fd822017-07-24 14:40:06 -040027 switch (primitiveTopology) {
Corentin Wallez1f6c8c42019-10-23 11:57:41 +000028 case wgpu::PrimitiveTopology::PointList:
Austin Engd81fd822017-07-24 14:40:06 -040029 return GL_POINTS;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +000030 case wgpu::PrimitiveTopology::LineList:
Austin Engd81fd822017-07-24 14:40:06 -040031 return GL_LINES;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +000032 case wgpu::PrimitiveTopology::LineStrip:
Austin Engd81fd822017-07-24 14:40:06 -040033 return GL_LINE_STRIP;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +000034 case wgpu::PrimitiveTopology::TriangleList:
Austin Engd81fd822017-07-24 14:40:06 -040035 return GL_TRIANGLES;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +000036 case wgpu::PrimitiveTopology::TriangleStrip:
Austin Engd81fd822017-07-24 14:40:06 -040037 return GL_TRIANGLE_STRIP;
Austin Engd81fd822017-07-24 14:40:06 -040038 }
Ben Clayton999cc242021-09-23 17:34:53 +000039 UNREACHABLE();
Austin Engd81fd822017-07-24 14:40:06 -040040 }
Yunchao He92700bf2018-12-27 06:32:31 +000041
Yunchao Hed2631f82019-07-06 00:11:10 +000042 void ApplyFrontFaceAndCulling(const OpenGLFunctions& gl,
Corentin Wallez1f6c8c42019-10-23 11:57:41 +000043 wgpu::FrontFace face,
44 wgpu::CullMode mode) {
Corentin Wallez7268e7d2020-08-18 12:30:06 +000045 // 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 Wallez1f6c8c42019-10-23 11:57:41 +000050 if (mode == wgpu::CullMode::None) {
Yunchao Hed2631f82019-07-06 00:11:10 +000051 gl.Disable(GL_CULL_FACE);
52 } else {
53 gl.Enable(GL_CULL_FACE);
Yunchao Hed2631f82019-07-06 00:11:10 +000054
Corentin Wallez1f6c8c42019-10-23 11:57:41 +000055 GLenum cullMode = (mode == wgpu::CullMode::Front) ? GL_FRONT : GL_BACK;
Yunchao Hed2631f82019-07-06 00:11:10 +000056 gl.CullFace(cullMode);
57 }
58 }
59
Corentin Wallez1f6c8c42019-10-23 11:57:41 +000060 GLenum GLBlendFactor(wgpu::BlendFactor factor, bool alpha) {
Yunchao He92700bf2018-12-27 06:32:31 +000061 switch (factor) {
Corentin Wallez1f6c8c42019-10-23 11:57:41 +000062 case wgpu::BlendFactor::Zero:
Yunchao He92700bf2018-12-27 06:32:31 +000063 return GL_ZERO;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +000064 case wgpu::BlendFactor::One:
Yunchao He92700bf2018-12-27 06:32:31 +000065 return GL_ONE;
Brandon Jones22b923c2021-04-15 18:34:29 +000066 case wgpu::BlendFactor::Src:
Yunchao He92700bf2018-12-27 06:32:31 +000067 return GL_SRC_COLOR;
Brandon Jones22b923c2021-04-15 18:34:29 +000068 case wgpu::BlendFactor::OneMinusSrc:
Yunchao He92700bf2018-12-27 06:32:31 +000069 return GL_ONE_MINUS_SRC_COLOR;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +000070 case wgpu::BlendFactor::SrcAlpha:
Yunchao He92700bf2018-12-27 06:32:31 +000071 return GL_SRC_ALPHA;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +000072 case wgpu::BlendFactor::OneMinusSrcAlpha:
Yunchao He92700bf2018-12-27 06:32:31 +000073 return GL_ONE_MINUS_SRC_ALPHA;
Brandon Jones22b923c2021-04-15 18:34:29 +000074 case wgpu::BlendFactor::Dst:
Yunchao He92700bf2018-12-27 06:32:31 +000075 return GL_DST_COLOR;
Brandon Jones22b923c2021-04-15 18:34:29 +000076 case wgpu::BlendFactor::OneMinusDst:
Yunchao He92700bf2018-12-27 06:32:31 +000077 return GL_ONE_MINUS_DST_COLOR;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +000078 case wgpu::BlendFactor::DstAlpha:
Yunchao He92700bf2018-12-27 06:32:31 +000079 return GL_DST_ALPHA;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +000080 case wgpu::BlendFactor::OneMinusDstAlpha:
Yunchao He92700bf2018-12-27 06:32:31 +000081 return GL_ONE_MINUS_DST_ALPHA;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +000082 case wgpu::BlendFactor::SrcAlphaSaturated:
Yunchao He92700bf2018-12-27 06:32:31 +000083 return GL_SRC_ALPHA_SATURATE;
Brandon Jones22b923c2021-04-15 18:34:29 +000084 case wgpu::BlendFactor::Constant:
Yunchao He92700bf2018-12-27 06:32:31 +000085 return alpha ? GL_CONSTANT_ALPHA : GL_CONSTANT_COLOR;
Brandon Jones22b923c2021-04-15 18:34:29 +000086 case wgpu::BlendFactor::OneMinusConstant:
Yunchao He92700bf2018-12-27 06:32:31 +000087 return alpha ? GL_ONE_MINUS_CONSTANT_ALPHA : GL_ONE_MINUS_CONSTANT_COLOR;
Yunchao He92700bf2018-12-27 06:32:31 +000088 }
Ben Clayton999cc242021-09-23 17:34:53 +000089 UNREACHABLE();
Yunchao He92700bf2018-12-27 06:32:31 +000090 }
91
Corentin Wallez1f6c8c42019-10-23 11:57:41 +000092 GLenum GLBlendMode(wgpu::BlendOperation operation) {
Yunchao He92700bf2018-12-27 06:32:31 +000093 switch (operation) {
Corentin Wallez1f6c8c42019-10-23 11:57:41 +000094 case wgpu::BlendOperation::Add:
Yunchao He92700bf2018-12-27 06:32:31 +000095 return GL_FUNC_ADD;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +000096 case wgpu::BlendOperation::Subtract:
Yunchao He92700bf2018-12-27 06:32:31 +000097 return GL_FUNC_SUBTRACT;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +000098 case wgpu::BlendOperation::ReverseSubtract:
Yunchao He92700bf2018-12-27 06:32:31 +000099 return GL_FUNC_REVERSE_SUBTRACT;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000100 case wgpu::BlendOperation::Min:
Yunchao He92700bf2018-12-27 06:32:31 +0000101 return GL_MIN;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000102 case wgpu::BlendOperation::Max:
Yunchao He92700bf2018-12-27 06:32:31 +0000103 return GL_MAX;
Yunchao He92700bf2018-12-27 06:32:31 +0000104 }
Ben Clayton999cc242021-09-23 17:34:53 +0000105 UNREACHABLE();
Yunchao He92700bf2018-12-27 06:32:31 +0000106 }
107
Corentin Wallezdf69f242019-06-13 10:22:32 +0000108 void ApplyColorState(const OpenGLFunctions& gl,
Austin Eng7b7e0982020-09-09 00:08:38 +0000109 ColorAttachmentIndex attachment,
Brandon Jones97da45c2021-03-22 22:17:26 +0000110 const ColorTargetState* state) {
Austin Eng7b7e0982020-09-09 00:08:38 +0000111 GLuint colorBuffer = static_cast<GLuint>(static_cast<uint8_t>(attachment));
Brandon Jones97da45c2021-03-22 22:17:26 +0000112 if (state->blend != nullptr) {
Stephen White04218412020-12-07 19:31:03 +0000113 gl.Enablei(GL_BLEND, colorBuffer);
Brandon Jones97da45c2021-03-22 22:17:26 +0000114 gl.BlendEquationSeparatei(colorBuffer, GLBlendMode(state->blend->color.operation),
115 GLBlendMode(state->blend->alpha.operation));
Stephen White04218412020-12-07 19:31:03 +0000116 gl.BlendFuncSeparatei(colorBuffer,
Brandon Jones97da45c2021-03-22 22:17:26 +0000117 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 He92700bf2018-12-27 06:32:31 +0000121 } else {
Stephen White04218412020-12-07 19:31:03 +0000122 gl.Disablei(GL_BLEND, colorBuffer);
Yunchao He92700bf2018-12-27 06:32:31 +0000123 }
Brandon Jones97da45c2021-03-22 22:17:26 +0000124 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 White04218412020-12-07 19:31:03 +0000128 }
129
Brandon Jones97da45c2021-03-22 22:17:26 +0000130 void ApplyColorState(const OpenGLFunctions& gl, const ColorTargetState* state) {
131 if (state->blend != nullptr) {
Stephen White04218412020-12-07 19:31:03 +0000132 gl.Enable(GL_BLEND);
Brandon Jones97da45c2021-03-22 22:17:26 +0000133 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 White04218412020-12-07 19:31:03 +0000139 } else {
140 gl.Disable(GL_BLEND);
141 }
Brandon Jones97da45c2021-03-22 22:17:26 +0000142 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 White04218412020-12-07 19:31:03 +0000146 }
147
Corentin Wallezda230e52021-08-23 10:10:11 +0000148 bool Equal(const BlendComponent& lhs, const BlendComponent& rhs) {
Stephen White04218412020-12-07 19:31:03 +0000149 return lhs.operation == rhs.operation && lhs.srcFactor == rhs.srcFactor &&
150 lhs.dstFactor == rhs.dstFactor;
Yunchao He92700bf2018-12-27 06:32:31 +0000151 }
152
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000153 GLuint OpenGLStencilOperation(wgpu::StencilOperation stencilOperation) {
Yunchao Heea563332019-01-04 04:28:37 +0000154 switch (stencilOperation) {
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000155 case wgpu::StencilOperation::Keep:
Yunchao Heea563332019-01-04 04:28:37 +0000156 return GL_KEEP;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000157 case wgpu::StencilOperation::Zero:
Yunchao Heea563332019-01-04 04:28:37 +0000158 return GL_ZERO;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000159 case wgpu::StencilOperation::Replace:
Yunchao Heea563332019-01-04 04:28:37 +0000160 return GL_REPLACE;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000161 case wgpu::StencilOperation::Invert:
Yunchao Heea563332019-01-04 04:28:37 +0000162 return GL_INVERT;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000163 case wgpu::StencilOperation::IncrementClamp:
Yunchao Heea563332019-01-04 04:28:37 +0000164 return GL_INCR;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000165 case wgpu::StencilOperation::DecrementClamp:
Yunchao Heea563332019-01-04 04:28:37 +0000166 return GL_DECR;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000167 case wgpu::StencilOperation::IncrementWrap:
Yunchao Heea563332019-01-04 04:28:37 +0000168 return GL_INCR_WRAP;
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000169 case wgpu::StencilOperation::DecrementWrap:
Yunchao Heea563332019-01-04 04:28:37 +0000170 return GL_DECR_WRAP;
Yunchao Heea563332019-01-04 04:28:37 +0000171 }
Ben Clayton999cc242021-09-23 17:34:53 +0000172 UNREACHABLE();
Yunchao Heea563332019-01-04 04:28:37 +0000173 }
174
Corentin Wallezdf69f242019-06-13 10:22:32 +0000175 void ApplyDepthStencilState(const OpenGLFunctions& gl,
Brandon Jones97da45c2021-03-22 22:17:26 +0000176 const DepthStencilState* descriptor,
Yunchao Heea563332019-01-04 04:28:37 +0000177 PersistentPipelineState* persistentPipelineState) {
178 // Depth writes only occur if depth is enabled
Corentin Wallez1f6c8c42019-10-23 11:57:41 +0000179 if (descriptor->depthCompare == wgpu::CompareFunction::Always &&
Yunchao Heea563332019-01-04 04:28:37 +0000180 !descriptor->depthWriteEnabled) {
Corentin Wallezdf69f242019-06-13 10:22:32 +0000181 gl.Disable(GL_DEPTH_TEST);
Yunchao Heea563332019-01-04 04:28:37 +0000182 } else {
Corentin Wallezdf69f242019-06-13 10:22:32 +0000183 gl.Enable(GL_DEPTH_TEST);
Yunchao Heea563332019-01-04 04:28:37 +0000184 }
185
186 if (descriptor->depthWriteEnabled) {
Corentin Wallezdf69f242019-06-13 10:22:32 +0000187 gl.DepthMask(GL_TRUE);
Yunchao Heea563332019-01-04 04:28:37 +0000188 } else {
Corentin Wallezdf69f242019-06-13 10:22:32 +0000189 gl.DepthMask(GL_FALSE);
Yunchao Heea563332019-01-04 04:28:37 +0000190 }
191
Corentin Wallezdf69f242019-06-13 10:22:32 +0000192 gl.DepthFunc(ToOpenGLCompareFunction(descriptor->depthCompare));
Yunchao Heea563332019-01-04 04:28:37 +0000193
194 if (StencilTestEnabled(descriptor)) {
Corentin Wallezdf69f242019-06-13 10:22:32 +0000195 gl.Enable(GL_STENCIL_TEST);
Yunchao Heea563332019-01-04 04:28:37 +0000196 } else {
Corentin Wallezdf69f242019-06-13 10:22:32 +0000197 gl.Disable(GL_STENCIL_TEST);
Yunchao Heea563332019-01-04 04:28:37 +0000198 }
199
Yunchao Hebaa37412019-01-30 21:11:43 +0000200 GLenum backCompareFunction = ToOpenGLCompareFunction(descriptor->stencilBack.compare);
201 GLenum frontCompareFunction = ToOpenGLCompareFunction(descriptor->stencilFront.compare);
Yunchao Heea563332019-01-04 04:28:37 +0000202 persistentPipelineState->SetStencilFuncsAndMask(
Corentin Wallezdf69f242019-06-13 10:22:32 +0000203 gl, backCompareFunction, frontCompareFunction, descriptor->stencilReadMask);
Yunchao Heea563332019-01-04 04:28:37 +0000204
Corentin Wallezdf69f242019-06-13 10:22:32 +0000205 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 Heea563332019-01-04 04:28:37 +0000211
Corentin Wallezdf69f242019-06-13 10:22:32 +0000212 gl.StencilMask(descriptor->stencilWriteMask);
Yunchao Heea563332019-01-04 04:28:37 +0000213 }
214
215 } // anonymous namespace
Austin Engd81fd822017-07-24 14:40:06 -0400216
Austin Eng8e957162021-08-03 19:07:29 +0000217 // static
Jiawei Shao3c0925b2021-09-29 00:49:01 +0000218 Ref<RenderPipeline> RenderPipeline::CreateUninitialized(
Austin Eng8e957162021-08-03 19:07:29 +0000219 Device* device,
220 const RenderPipelineDescriptor* descriptor) {
Jiawei Shao3c0925b2021-09-29 00:49:01 +0000221 return AcquireRef(new RenderPipeline(device, descriptor));
Austin Eng8e957162021-08-03 19:07:29 +0000222 }
223
Brandon Jones41c87d92021-05-21 05:01:38 +0000224 RenderPipeline::RenderPipeline(Device* device, const RenderPipelineDescriptor* descriptor)
Yan, Shaoboa4924272018-12-10 19:47:22 +0000225 : RenderPipelineBase(device, descriptor),
Yunchao He889d7432019-03-27 18:08:50 +0000226 mVertexArrayObject(0),
Corentin Wallez7ee16102017-11-23 11:24:20 -0800227 mGlPrimitiveTopology(GLPrimitiveTopology(GetPrimitiveTopology())) {
Austin Eng8e957162021-08-03 19:07:29 +0000228 }
Corentin Wallez8e335a52018-08-27 23:12:56 +0200229
Austin Eng8e957162021-08-03 19:07:29 +0000230 MaybeError RenderPipeline::Initialize() {
231 DAWN_TRY(
232 InitializeBase(ToBackend(GetDevice())->gl, ToBackend(GetLayout()), GetAllStages()));
Brandon Jonesf7592642021-04-02 19:42:28 +0000233 CreateVAOForVertexState();
Austin Eng8e957162021-08-03 19:07:29 +0000234 return {};
Yunchao He889d7432019-03-27 18:08:50 +0000235 }
236
Loko Kung2c67af92021-11-11 00:39:22 +0000237 RenderPipeline::~RenderPipeline() = default;
238
Loko Kunge9c84c02021-11-11 01:39:52 +0000239 void RenderPipeline::DestroyImpl() {
Loko Kung6331f952021-12-01 18:54:40 +0000240 RenderPipelineBase::DestroyImpl();
Corentin Wallezdf69f242019-06-13 10:22:32 +0000241 const OpenGLFunctions& gl = ToBackend(GetDevice())->gl;
242 gl.DeleteVertexArrays(1, &mVertexArrayObject);
243 gl.BindVertexArray(0);
Jiawei Shaoafe91382021-10-04 12:31:22 +0000244 DeleteProgram(gl);
Austin Engd81fd822017-07-24 14:40:06 -0400245 }
246
247 GLenum RenderPipeline::GetGLPrimitiveTopology() const {
Corentin Wallez7ee16102017-11-23 11:24:20 -0800248 return mGlPrimitiveTopology;
Corentin Wallezb085eec2017-07-14 14:04:52 -0400249 }
250
Austin Eng4099f652020-09-17 19:07:00 +0000251 ityp::bitset<VertexAttributeLocation, kMaxVertexAttributes>
252 RenderPipeline::GetAttributesUsingVertexBuffer(VertexBufferSlot slot) const {
253 ASSERT(!IsError());
254 return mAttributesUsingVertexBuffer[slot];
255 }
256
Brandon Jonesf7592642021-04-02 19:42:28 +0000257 void RenderPipeline::CreateVAOForVertexState() {
Corentin Wallezdf69f242019-06-13 10:22:32 +0000258 const OpenGLFunctions& gl = ToBackend(GetDevice())->gl;
259
260 gl.GenVertexArrays(1, &mVertexArrayObject);
261 gl.BindVertexArray(mVertexArrayObject);
262
Austin Eng4099f652020-09-17 19:07:00 +0000263 for (VertexAttributeLocation location : IterateBitSet(GetAttributeLocationsUsed())) {
Yunchao He494552b2019-03-28 10:57:41 +0000264 const auto& attribute = GetAttribute(location);
Austin Eng4099f652020-09-17 19:07:00 +0000265 GLuint glAttrib = static_cast<GLuint>(static_cast<uint8_t>(location));
266 gl.EnableVertexAttribArray(glAttrib);
Yunchao He889d7432019-03-27 18:08:50 +0000267
Austin Eng4099f652020-09-17 19:07:00 +0000268 mAttributesUsingVertexBuffer[attribute.vertexBufferSlot][location] = true;
Kai Ninomiyaae1f25f2019-11-07 22:23:29 +0000269 const VertexBufferInfo& vertexBuffer = GetVertexBuffer(attribute.vertexBufferSlot);
Yunchao He889d7432019-03-27 18:08:50 +0000270
Kai Ninomiyaae1f25f2019-11-07 22:23:29 +0000271 if (vertexBuffer.arrayStride == 0) {
Yunchao He889d7432019-03-27 18:08:50 +0000272 // Emulate a stride of zero (constant vertex attribute) by
273 // setting the attribute instance divisor to a huge number.
Austin Eng4099f652020-09-17 19:07:00 +0000274 gl.VertexAttribDivisor(glAttrib, 0xffffffff);
Yunchao He889d7432019-03-27 18:08:50 +0000275 } else {
Kai Ninomiyaae1f25f2019-11-07 22:23:29 +0000276 switch (vertexBuffer.stepMode) {
Corentin Wallezff6c9ca62021-07-25 18:40:19 +0000277 case wgpu::VertexStepMode::Vertex:
Yunchao He889d7432019-03-27 18:08:50 +0000278 break;
Corentin Wallezff6c9ca62021-07-25 18:40:19 +0000279 case wgpu::VertexStepMode::Instance:
Austin Eng4099f652020-09-17 19:07:00 +0000280 gl.VertexAttribDivisor(glAttrib, 1);
Yunchao He889d7432019-03-27 18:08:50 +0000281 break;
Yunchao He889d7432019-03-27 18:08:50 +0000282 }
283 }
284 }
285 }
286
Corentin Wallezc7807ab2017-11-24 14:16:15 -0500287 void RenderPipeline::ApplyNow(PersistentPipelineState& persistentPipelineState) {
Corentin Wallezdf69f242019-06-13 10:22:32 +0000288 const OpenGLFunctions& gl = ToBackend(GetDevice())->gl;
289 PipelineGL::ApplyNow(gl);
Corentin Wallezb085eec2017-07-14 14:04:52 -0400290
Yunchao He889d7432019-03-27 18:08:50 +0000291 ASSERT(mVertexArrayObject);
Corentin Wallezdf69f242019-06-13 10:22:32 +0000292 gl.BindVertexArray(mVertexArrayObject);
Corentin Wallezb085eec2017-07-14 14:04:52 -0400293
Yunchao Hed2631f82019-07-06 00:11:10 +0000294 ApplyFrontFaceAndCulling(gl, GetFrontFace(), GetCullMode());
295
Brandon Jones97da45c2021-03-22 22:17:26 +0000296 ApplyDepthStencilState(gl, GetDepthStencilState(), &persistentPipelineState);
Austin Eng8dc3bd12017-08-01 18:22:57 -0400297
Corentin Wallezc7ae7a02020-07-23 16:26:16 +0000298 gl.SampleMaski(0, GetSampleMask());
Tomek Ponitkaab04da42020-07-29 11:44:41 +0000299 if (IsAlphaToCoverageEnabled()) {
300 gl.Enable(GL_SAMPLE_ALPHA_TO_COVERAGE);
301 } else {
302 gl.Disable(GL_SAMPLE_ALPHA_TO_COVERAGE);
303 }
Corentin Wallezc7ae7a02020-07-23 16:26:16 +0000304
Enrico Gallidb2c2dd2020-10-06 08:12:29 +0000305 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 White04218412020-12-07 19:31:03 +0000318 if (!GetDevice()->IsToggleEnabled(Toggle::DisableIndexedDrawBuffers)) {
319 for (ColorAttachmentIndex attachmentSlot : IterateBitSet(GetColorAttachmentsMask())) {
Brandon Jones97da45c2021-03-22 22:17:26 +0000320 ApplyColorState(gl, attachmentSlot, GetColorTargetState(attachmentSlot));
Stephen White04218412020-12-07 19:31:03 +0000321 }
322 } else {
Brandon Jones97da45c2021-03-22 22:17:26 +0000323 const ColorTargetState* prevDescriptor = nullptr;
Stephen White04218412020-12-07 19:31:03 +0000324 for (ColorAttachmentIndex attachmentSlot : IterateBitSet(GetColorAttachmentsMask())) {
Brandon Jones97da45c2021-03-22 22:17:26 +0000325 const ColorTargetState* descriptor = GetColorTargetState(attachmentSlot);
Stephen White04218412020-12-07 19:31:03 +0000326 if (!prevDescriptor) {
327 ApplyColorState(gl, descriptor);
328 prevDescriptor = descriptor;
Brandon Jones97da45c2021-03-22 22:17:26 +0000329 } 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 White04218412020-12-07 19:31:03 +0000332 ASSERT(false);
Brandon Jones97da45c2021-03-22 22:17:26 +0000333 } 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 White04218412020-12-07 19:31:03 +0000340 }
341 }
Austin Eng8dc3bd12017-08-01 18:22:57 -0400342 }
Corentin Wallezb085eec2017-07-14 14:04:52 -0400343 }
344
Corentin Wallez49a65d02018-07-24 16:45:45 +0200345}} // namespace dawn_native::opengl