blob: 8fbdca96324597d576222e1279976fa74fa36928 [file] [log] [blame]
Geoff Langf9a6f082015-01-22 13:32:49 -05001//
2// Copyright 2015 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// RendererGL.cpp: Implements the class methods for RendererGL.
8
9#include "libANGLE/renderer/gl/RendererGL.h"
10
Jamie Madill39fcf262015-06-08 14:39:07 -040011#include <EGL/eglext.h>
12
Geoff Langf9a6f082015-01-22 13:32:49 -050013#include "common/debug.h"
Jamie Madill39fcf262015-06-08 14:39:07 -040014#include "libANGLE/AttributeMap.h"
Jamie Madill9082b982016-04-27 15:21:51 -040015#include "libANGLE/ContextState.h"
Geoff Lang4ad17092015-03-10 16:47:44 -040016#include "libANGLE/Surface.h"
Geoff Lang53b8aec2015-08-24 10:33:25 -040017#include "libANGLE/renderer/gl/BlitGL.h"
Geoff Langf9a6f082015-01-22 13:32:49 -050018#include "libANGLE/renderer/gl/BufferGL.h"
19#include "libANGLE/renderer/gl/CompilerGL.h"
Jamie Madill437fa652016-05-03 15:13:24 -040020#include "libANGLE/renderer/gl/ContextGL.h"
Geoff Langf9a6f082015-01-22 13:32:49 -050021#include "libANGLE/renderer/gl/FenceNVGL.h"
22#include "libANGLE/renderer/gl/FenceSyncGL.h"
23#include "libANGLE/renderer/gl/FramebufferGL.h"
Geoff Lang56cf9af2015-02-17 10:16:49 -050024#include "libANGLE/renderer/gl/FunctionsGL.h"
Geoff Langf9a6f082015-01-22 13:32:49 -050025#include "libANGLE/renderer/gl/ProgramGL.h"
26#include "libANGLE/renderer/gl/QueryGL.h"
27#include "libANGLE/renderer/gl/RenderbufferGL.h"
Geoff Lang0af0b812015-09-23 13:56:25 -040028#include "libANGLE/renderer/gl/SamplerGL.h"
Geoff Langf9a6f082015-01-22 13:32:49 -050029#include "libANGLE/renderer/gl/ShaderGL.h"
Geoff Lang94463d52015-02-18 13:09:37 -050030#include "libANGLE/renderer/gl/StateManagerGL.h"
Geoff Lang4ad17092015-03-10 16:47:44 -040031#include "libANGLE/renderer/gl/SurfaceGL.h"
Geoff Langf9a6f082015-01-22 13:32:49 -050032#include "libANGLE/renderer/gl/TextureGL.h"
33#include "libANGLE/renderer/gl/TransformFeedbackGL.h"
34#include "libANGLE/renderer/gl/VertexArrayGL.h"
Geoff Langddc74462015-02-25 11:48:09 -050035#include "libANGLE/renderer/gl/renderergl_utils.h"
Geoff Langf9a6f082015-01-22 13:32:49 -050036
Geoff Langb80360f2015-05-04 15:01:31 -040037#ifndef NDEBUG
38static void INTERNAL_GL_APIENTRY LogGLDebugMessage(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length,
39 const GLchar *message, const void *userParam)
40{
41 std::string sourceText;
42 switch (source)
43 {
44 case GL_DEBUG_SOURCE_API: sourceText = "OpenGL"; break;
45 case GL_DEBUG_SOURCE_WINDOW_SYSTEM: sourceText = "Windows"; break;
46 case GL_DEBUG_SOURCE_SHADER_COMPILER: sourceText = "Shader Compiler"; break;
47 case GL_DEBUG_SOURCE_THIRD_PARTY: sourceText = "Third Party"; break;
48 case GL_DEBUG_SOURCE_APPLICATION: sourceText = "Application"; break;
49 case GL_DEBUG_SOURCE_OTHER: sourceText = "Other"; break;
50 default: sourceText = "UNKNOWN"; break;
51 }
52
53 std::string typeText;
54 switch (type)
55 {
56 case GL_DEBUG_TYPE_ERROR: typeText = "Error"; break;
57 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: typeText = "Deprecated behavior"; break;
58 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: typeText = "Undefined behavior"; break;
59 case GL_DEBUG_TYPE_PORTABILITY: typeText = "Portability"; break;
60 case GL_DEBUG_TYPE_PERFORMANCE: typeText = "Performance"; break;
61 case GL_DEBUG_TYPE_OTHER: typeText = "Other"; break;
62 case GL_DEBUG_TYPE_MARKER: typeText = "Marker"; break;
63 default: typeText = "UNKNOWN"; break;
64 }
65
66 std::string severityText;
67 switch (severity)
68 {
69 case GL_DEBUG_SEVERITY_HIGH: severityText = "High"; break;
70 case GL_DEBUG_SEVERITY_MEDIUM: severityText = "Medium"; break;
71 case GL_DEBUG_SEVERITY_LOW: severityText = "Low"; break;
72 case GL_DEBUG_SEVERITY_NOTIFICATION: severityText = "Notification"; break;
73 default: severityText = "UNKNOWN"; break;
74 }
75
76 ERR("\n\tSource: %s\n\tType: %s\n\tID: %d\n\tSeverity: %s\n\tMessage: %s", sourceText.c_str(), typeText.c_str(), id,
77 severityText.c_str(), message);
78}
79#endif
80
Geoff Langf9a6f082015-01-22 13:32:49 -050081namespace rx
82{
83
Jamie Madill39fcf262015-06-08 14:39:07 -040084RendererGL::RendererGL(const FunctionsGL *functions, const egl::AttributeMap &attribMap)
Jamie Madill53ea9cc2016-05-17 10:12:52 -040085 : mMaxSupportedESVersion(0, 0),
Geoff Lang94463d52015-02-18 13:09:37 -050086 mFunctions(functions),
Jamie Madill39fcf262015-06-08 14:39:07 -040087 mStateManager(nullptr),
Geoff Lang53b8aec2015-08-24 10:33:25 -040088 mBlitter(nullptr),
Geoff Langf0aa8422015-09-29 15:08:34 -040089 mHasDebugOutput(false),
Jamie Madill53ea9cc2016-05-17 10:12:52 -040090 mSkipDrawCalls(false),
91 mCapsInitialized(false)
Geoff Lang56cf9af2015-02-17 10:16:49 -050092{
93 ASSERT(mFunctions);
Jamie Madill53ea9cc2016-05-17 10:12:52 -040094 mStateManager = new StateManagerGL(mFunctions, getNativeCaps());
Geoff Langcab7e1d2015-07-27 11:20:41 -040095 nativegl_gl::GenerateWorkarounds(mFunctions, &mWorkarounds);
Geoff Lang53b8aec2015-08-24 10:33:25 -040096 mBlitter = new BlitGL(functions, mWorkarounds, mStateManager);
Geoff Langb80360f2015-05-04 15:01:31 -040097
Geoff Langf0aa8422015-09-29 15:08:34 -040098 mHasDebugOutput = mFunctions->isAtLeastGL(gl::Version(4, 3)) ||
99 mFunctions->hasGLExtension("GL_KHR_debug") ||
100 mFunctions->isAtLeastGLES(gl::Version(3, 2)) ||
101 mFunctions->hasGLESExtension("GL_KHR_debug");
Geoff Langb80360f2015-05-04 15:01:31 -0400102#ifndef NDEBUG
Geoff Langf0aa8422015-09-29 15:08:34 -0400103 if (mHasDebugOutput)
Geoff Langb80360f2015-05-04 15:01:31 -0400104 {
105 mFunctions->enable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
106 mFunctions->debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_HIGH, 0, nullptr, GL_TRUE);
107 mFunctions->debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_MEDIUM, 0, nullptr, GL_TRUE);
108 mFunctions->debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW, 0, nullptr, GL_FALSE);
109 mFunctions->debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_NOTIFICATION, 0, nullptr, GL_FALSE);
110 mFunctions->debugMessageCallback(&LogGLDebugMessage, nullptr);
111 }
112#endif
Jamie Madill39fcf262015-06-08 14:39:07 -0400113
Ian Ewellec2c0c52016-04-05 13:46:26 -0400114 EGLint deviceType =
115 static_cast<EGLint>(attribMap.get(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_NONE));
Jamie Madill39fcf262015-06-08 14:39:07 -0400116 if (deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE)
117 {
118 mSkipDrawCalls = true;
119 }
Geoff Lang56cf9af2015-02-17 10:16:49 -0500120}
Geoff Langf9a6f082015-01-22 13:32:49 -0500121
122RendererGL::~RendererGL()
Geoff Lang94463d52015-02-18 13:09:37 -0500123{
Geoff Lang53b8aec2015-08-24 10:33:25 -0400124 SafeDelete(mBlitter);
Geoff Langbf8a72f2015-11-03 16:34:45 -0500125 SafeDelete(mStateManager);
Geoff Lang94463d52015-02-18 13:09:37 -0500126}
Geoff Langf9a6f082015-01-22 13:32:49 -0500127
128gl::Error RendererGL::flush()
129{
Geoff Lang2c919142015-04-01 14:44:13 -0400130 mFunctions->flush();
131 return gl::Error(GL_NO_ERROR);
Geoff Langf9a6f082015-01-22 13:32:49 -0500132}
133
134gl::Error RendererGL::finish()
135{
Geoff Langf0aa8422015-09-29 15:08:34 -0400136#ifdef NDEBUG
137 if (mWorkarounds.finishDoesNotCauseQueriesToBeAvailable && mHasDebugOutput)
138 {
139 mFunctions->enable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
140 }
141#endif
142
Geoff Lang2c919142015-04-01 14:44:13 -0400143 mFunctions->finish();
Geoff Langf0aa8422015-09-29 15:08:34 -0400144
145#ifdef NDEBUG
146 if (mWorkarounds.finishDoesNotCauseQueriesToBeAvailable && mHasDebugOutput)
147 {
148 mFunctions->disable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
149 }
150#endif
151
Geoff Lang2c919142015-04-01 14:44:13 -0400152 return gl::Error(GL_NO_ERROR);
Geoff Langf9a6f082015-01-22 13:32:49 -0500153}
154
Jamie Madill9082b982016-04-27 15:21:51 -0400155gl::Error RendererGL::drawArrays(const gl::ContextState &data,
156 GLenum mode,
157 GLint first,
158 GLsizei count)
Geoff Langf9a6f082015-01-22 13:32:49 -0500159{
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400160 ANGLE_TRY(mStateManager->setDrawArraysState(data, first, count, 0));
Geoff Lang7c82bc42015-03-09 16:18:08 -0400161
Jamie Madill39fcf262015-06-08 14:39:07 -0400162 if (!mSkipDrawCalls)
163 {
164 mFunctions->drawArrays(mode, first, count);
165 }
Geoff Langd6e50872015-02-24 12:42:26 -0500166
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400167 return gl::NoError();
Geoff Langf9a6f082015-01-22 13:32:49 -0500168}
169
Jamie Madill9082b982016-04-27 15:21:51 -0400170gl::Error RendererGL::drawArraysInstanced(const gl::ContextState &data,
Geoff Langf6db0982015-08-25 13:04:00 -0400171 GLenum mode,
172 GLint first,
173 GLsizei count,
174 GLsizei instanceCount)
175{
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400176 ANGLE_TRY(mStateManager->setDrawArraysState(data, first, count, instanceCount));
Geoff Lang3cf12ce2015-08-27 14:40:48 -0400177
178 if (!mSkipDrawCalls)
179 {
180 mFunctions->drawArraysInstanced(mode, first, count, instanceCount);
181 }
182
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400183 return gl::NoError();
Geoff Langf6db0982015-08-25 13:04:00 -0400184}
185
Jamie Madill9082b982016-04-27 15:21:51 -0400186gl::Error RendererGL::drawElements(const gl::ContextState &data,
Geoff Langf6db0982015-08-25 13:04:00 -0400187 GLenum mode,
188 GLsizei count,
189 GLenum type,
190 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -0400191 const gl::IndexRange &indexRange)
Geoff Langf9a6f082015-01-22 13:32:49 -0500192{
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400193 const GLvoid *drawIndexPtr = nullptr;
194 ANGLE_TRY(mStateManager->setDrawElementsState(data, count, type, indices, 0, &drawIndexPtr));
Geoff Lang7c82bc42015-03-09 16:18:08 -0400195
Jamie Madill39fcf262015-06-08 14:39:07 -0400196 if (!mSkipDrawCalls)
197 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400198 mFunctions->drawElements(mode, count, type, drawIndexPtr);
Jamie Madill39fcf262015-06-08 14:39:07 -0400199 }
Geoff Langd6e50872015-02-24 12:42:26 -0500200
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400201 return gl::NoError();
Geoff Langf9a6f082015-01-22 13:32:49 -0500202}
203
Jamie Madill9082b982016-04-27 15:21:51 -0400204gl::Error RendererGL::drawElementsInstanced(const gl::ContextState &data,
Geoff Langf6db0982015-08-25 13:04:00 -0400205 GLenum mode,
206 GLsizei count,
207 GLenum type,
208 const GLvoid *indices,
209 GLsizei instances,
Geoff Lang3edfe032015-09-04 16:38:24 -0400210 const gl::IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -0400211{
Geoff Lang3cf12ce2015-08-27 14:40:48 -0400212 const GLvoid *drawIndexPointer = nullptr;
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400213 ANGLE_TRY(mStateManager->setDrawElementsState(data, count, type, indices, instances,
214 &drawIndexPointer));
Geoff Lang3cf12ce2015-08-27 14:40:48 -0400215
216 if (!mSkipDrawCalls)
217 {
218 mFunctions->drawElementsInstanced(mode, count, type, drawIndexPointer, instances);
219 }
220
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400221 return gl::NoError();
Geoff Langf6db0982015-08-25 13:04:00 -0400222}
223
Jamie Madill9082b982016-04-27 15:21:51 -0400224gl::Error RendererGL::drawRangeElements(const gl::ContextState &data,
Geoff Langf6db0982015-08-25 13:04:00 -0400225 GLenum mode,
226 GLuint start,
227 GLuint end,
228 GLsizei count,
229 GLenum type,
230 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -0400231 const gl::IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -0400232{
Geoff Lang47502232015-08-25 16:26:10 -0400233 const GLvoid *drawIndexPointer = nullptr;
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400234 ANGLE_TRY(
235 mStateManager->setDrawElementsState(data, count, type, indices, 0, &drawIndexPointer));
Geoff Lang47502232015-08-25 16:26:10 -0400236
237 if (!mSkipDrawCalls)
238 {
239 mFunctions->drawRangeElements(mode, start, end, count, type, drawIndexPointer);
240 }
241
Geoff Langf6db0982015-08-25 13:04:00 -0400242 return gl::Error(GL_NO_ERROR);
243}
244
Jamie Madill8415b5f2016-04-26 13:41:39 -0400245ContextImpl *RendererGL::createContext(const gl::ContextState &state)
Jamie Madill437fa652016-05-03 15:13:24 -0400246{
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400247 return new ContextGL(state, this);
Geoff Lang0af0b812015-09-23 13:56:25 -0400248}
249
Geoff Langf6ade2e2015-09-29 11:21:43 -0400250void RendererGL::insertEventMarker(GLsizei length, const char *marker)
Austin Kinross6ee1e782015-05-29 17:05:37 -0700251{
Geoff Langf6ade2e2015-09-29 11:21:43 -0400252 mFunctions->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_MARKER, 0,
253 GL_DEBUG_SEVERITY_NOTIFICATION, length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -0700254}
255
Geoff Langf6ade2e2015-09-29 11:21:43 -0400256void RendererGL::pushGroupMarker(GLsizei length, const char *marker)
Austin Kinross6ee1e782015-05-29 17:05:37 -0700257{
Geoff Langf6ade2e2015-09-29 11:21:43 -0400258 mFunctions->pushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -0700259}
260
261void RendererGL::popGroupMarker()
262{
Geoff Langf6ade2e2015-09-29 11:21:43 -0400263 mFunctions->popDebugGroup();
Austin Kinross6ee1e782015-05-29 17:05:37 -0700264}
265
Geoff Langf9a6f082015-01-22 13:32:49 -0500266void RendererGL::notifyDeviceLost()
267{
268 UNIMPLEMENTED();
269}
270
271bool RendererGL::isDeviceLost() const
272{
273 UNIMPLEMENTED();
274 return bool();
275}
276
277bool RendererGL::testDeviceLost()
278{
279 UNIMPLEMENTED();
280 return bool();
281}
282
283bool RendererGL::testDeviceResettable()
284{
285 UNIMPLEMENTED();
286 return bool();
287}
288
Geoff Langf9a6f082015-01-22 13:32:49 -0500289std::string RendererGL::getVendorString() const
290{
Geoff Lange42753b2015-04-08 13:46:33 -0400291 return std::string(reinterpret_cast<const char*>(mFunctions->getString(GL_VENDOR)));
Geoff Langf9a6f082015-01-22 13:32:49 -0500292}
293
294std::string RendererGL::getRendererDescription() const
295{
Geoff Lange42753b2015-04-08 13:46:33 -0400296 std::string nativeVendorString(reinterpret_cast<const char*>(mFunctions->getString(GL_VENDOR)));
297 std::string nativeRendererString(reinterpret_cast<const char*>(mFunctions->getString(GL_RENDERER)));
298
Geoff Lange42753b2015-04-08 13:46:33 -0400299 std::ostringstream rendererString;
300 rendererString << nativeVendorString << " " << nativeRendererString << " OpenGL";
Geoff Lang08dcfed2015-05-25 13:38:42 -0400301 if (mFunctions->standard == STANDARD_GL_ES)
Geoff Lange42753b2015-04-08 13:46:33 -0400302 {
303 rendererString << " ES";
304 }
Geoff Lang08dcfed2015-05-25 13:38:42 -0400305 rendererString << " " << mFunctions->version.major << "." << mFunctions->version.minor;
Geoff Lang8b0f0b32015-07-20 15:59:28 -0400306 if (mFunctions->standard == STANDARD_GL_DESKTOP)
307 {
308 // Some drivers (NVIDIA) use a profile mask of 0 when in compatibility profile.
309 if ((mFunctions->profile & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) != 0 ||
310 (mFunctions->isAtLeastGL(gl::Version(3, 2)) && mFunctions->profile == 0))
311 {
312 rendererString << " compatibility";
313 }
314 else if ((mFunctions->profile & GL_CONTEXT_CORE_PROFILE_BIT) != 0)
315 {
316 rendererString << " core";
317 }
318 }
Geoff Lange42753b2015-04-08 13:46:33 -0400319
320 return rendererString.str();
Geoff Langf9a6f082015-01-22 13:32:49 -0500321}
322
Geoff Lang862c0ba2015-05-25 15:31:16 -0400323const gl::Version &RendererGL::getMaxSupportedESVersion() const
324{
325 // Force generation of caps
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400326 getNativeCaps();
Geoff Lang862c0ba2015-05-25 15:31:16 -0400327
328 return mMaxSupportedESVersion;
329}
330
Austin Kinross02df7962015-07-01 10:03:42 -0700331void RendererGL::generateCaps(gl::Caps *outCaps, gl::TextureCapsMap* outTextureCaps,
332 gl::Extensions *outExtensions,
333 gl::Limitations * /* outLimitations */) const
Geoff Langf9a6f082015-01-22 13:32:49 -0500334{
Geoff Lang862c0ba2015-05-25 15:31:16 -0400335 nativegl_gl::GenerateCaps(mFunctions, outCaps, outTextureCaps, outExtensions, &mMaxSupportedESVersion);
Geoff Langf9a6f082015-01-22 13:32:49 -0500336}
337
Ian Ewell53f59f42016-01-28 17:36:55 -0500338GLint RendererGL::getGPUDisjoint()
339{
340 // TODO(ewell): On GLES backends we should find a way to reliably query disjoint events
341 return 0;
342}
343
344GLint64 RendererGL::getTimestamp()
345{
346 GLint64 result = 0;
347 mFunctions->getInteger64v(GL_TIMESTAMP, &result);
348 return result;
349}
Ian Ewell292f0052016-02-04 10:37:32 -0500350
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400351void RendererGL::ensureCapsInitialized() const
Ian Ewell292f0052016-02-04 10:37:32 -0500352{
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400353 if (!mCapsInitialized)
354 {
355 generateCaps(&mNativeCaps, &mNativeTextureCaps, &mNativeExtensions, &mNativeLimitations);
356 mCapsInitialized = true;
357 }
Ian Ewell292f0052016-02-04 10:37:32 -0500358}
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400359
360const gl::Caps &RendererGL::getNativeCaps() const
361{
362 ensureCapsInitialized();
363 return mNativeCaps;
Geoff Langf9a6f082015-01-22 13:32:49 -0500364}
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400365
366const gl::TextureCapsMap &RendererGL::getNativeTextureCaps() const
367{
368 ensureCapsInitialized();
369 return mNativeTextureCaps;
370}
371
372const gl::Extensions &RendererGL::getNativeExtensions() const
373{
374 ensureCapsInitialized();
375 return mNativeExtensions;
376}
377
378const gl::Limitations &RendererGL::getNativeLimitations() const
379{
380 ensureCapsInitialized();
381 return mNativeLimitations;
382}
383
384} // namespace rx