gl_rasterizer.cpp 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312
  1. // Copyright 2015 Citra Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include <algorithm>
  5. #include <array>
  6. #include <bitset>
  7. #include <memory>
  8. #include <string>
  9. #include <string_view>
  10. #include <tuple>
  11. #include <utility>
  12. #include <glad/glad.h>
  13. #include "common/alignment.h"
  14. #include "common/assert.h"
  15. #include "common/logging/log.h"
  16. #include "common/math_util.h"
  17. #include "common/microprofile.h"
  18. #include "common/scope_exit.h"
  19. #include "core/core.h"
  20. #include "core/hle/kernel/process.h"
  21. #include "core/memory.h"
  22. #include "core/settings.h"
  23. #include "video_core/engines/kepler_compute.h"
  24. #include "video_core/engines/maxwell_3d.h"
  25. #include "video_core/engines/shader_type.h"
  26. #include "video_core/memory_manager.h"
  27. #include "video_core/renderer_opengl/gl_rasterizer.h"
  28. #include "video_core/renderer_opengl/gl_shader_cache.h"
  29. #include "video_core/renderer_opengl/gl_shader_gen.h"
  30. #include "video_core/renderer_opengl/maxwell_to_gl.h"
  31. #include "video_core/renderer_opengl/renderer_opengl.h"
  32. namespace OpenGL {
  33. using Maxwell = Tegra::Engines::Maxwell3D::Regs;
  34. using VideoCore::Surface::PixelFormat;
  35. using VideoCore::Surface::SurfaceTarget;
  36. using VideoCore::Surface::SurfaceType;
  37. MICROPROFILE_DEFINE(OpenGL_VAO, "OpenGL", "Vertex Format Setup", MP_RGB(128, 128, 192));
  38. MICROPROFILE_DEFINE(OpenGL_VB, "OpenGL", "Vertex Buffer Setup", MP_RGB(128, 128, 192));
  39. MICROPROFILE_DEFINE(OpenGL_Shader, "OpenGL", "Shader Setup", MP_RGB(128, 128, 192));
  40. MICROPROFILE_DEFINE(OpenGL_UBO, "OpenGL", "Const Buffer Setup", MP_RGB(128, 128, 192));
  41. MICROPROFILE_DEFINE(OpenGL_Index, "OpenGL", "Index Buffer Setup", MP_RGB(128, 128, 192));
  42. MICROPROFILE_DEFINE(OpenGL_Texture, "OpenGL", "Texture Setup", MP_RGB(128, 128, 192));
  43. MICROPROFILE_DEFINE(OpenGL_Framebuffer, "OpenGL", "Framebuffer Setup", MP_RGB(128, 128, 192));
  44. MICROPROFILE_DEFINE(OpenGL_Drawing, "OpenGL", "Drawing", MP_RGB(128, 128, 192));
  45. MICROPROFILE_DEFINE(OpenGL_Blits, "OpenGL", "Blits", MP_RGB(128, 128, 192));
  46. MICROPROFILE_DEFINE(OpenGL_CacheManagement, "OpenGL", "Cache Mgmt", MP_RGB(100, 255, 100));
  47. MICROPROFILE_DEFINE(OpenGL_PrimitiveAssembly, "OpenGL", "Prim Asmbl", MP_RGB(255, 100, 100));
  48. namespace {
  49. template <typename Engine, typename Entry>
  50. Tegra::Texture::FullTextureInfo GetTextureInfo(const Engine& engine, const Entry& entry,
  51. Tegra::Engines::ShaderType shader_type) {
  52. if (entry.IsBindless()) {
  53. const Tegra::Texture::TextureHandle tex_handle =
  54. engine.AccessConstBuffer32(shader_type, entry.GetBuffer(), entry.GetOffset());
  55. return engine.GetTextureInfo(tex_handle);
  56. }
  57. if constexpr (std::is_same_v<Engine, Tegra::Engines::Maxwell3D>) {
  58. return engine.GetStageTexture(shader_type, entry.GetOffset());
  59. } else {
  60. return engine.GetTexture(entry.GetOffset());
  61. }
  62. }
  63. std::size_t GetConstBufferSize(const Tegra::Engines::ConstBufferInfo& buffer,
  64. const GLShader::ConstBufferEntry& entry) {
  65. if (!entry.IsIndirect()) {
  66. return entry.GetSize();
  67. }
  68. if (buffer.size > Maxwell::MaxConstBufferSize) {
  69. LOG_WARNING(Render_OpenGL, "Indirect constbuffer size {} exceeds maximum {}", buffer.size,
  70. Maxwell::MaxConstBufferSize);
  71. return Maxwell::MaxConstBufferSize;
  72. }
  73. return buffer.size;
  74. }
  75. } // Anonymous namespace
  76. RasterizerOpenGL::RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window,
  77. ScreenInfo& info)
  78. : RasterizerAccelerated{system.Memory()}, texture_cache{system, *this, device},
  79. shader_cache{*this, system, emu_window, device}, system{system}, screen_info{info},
  80. buffer_cache{*this, system, device, STREAM_BUFFER_SIZE} {
  81. shader_program_manager = std::make_unique<GLShader::ProgramManager>();
  82. state.draw.shader_program = 0;
  83. state.Apply();
  84. LOG_DEBUG(Render_OpenGL, "Sync fixed function OpenGL state here");
  85. CheckExtensions();
  86. }
  87. RasterizerOpenGL::~RasterizerOpenGL() {}
  88. void RasterizerOpenGL::CheckExtensions() {
  89. if (!GLAD_GL_ARB_texture_filter_anisotropic && !GLAD_GL_EXT_texture_filter_anisotropic) {
  90. LOG_WARNING(
  91. Render_OpenGL,
  92. "Anisotropic filter is not supported! This can cause graphical issues in some games.");
  93. }
  94. }
  95. GLuint RasterizerOpenGL::SetupVertexFormat() {
  96. auto& gpu = system.GPU().Maxwell3D();
  97. const auto& regs = gpu.regs;
  98. if (!gpu.dirty.vertex_attrib_format) {
  99. return state.draw.vertex_array;
  100. }
  101. gpu.dirty.vertex_attrib_format = false;
  102. MICROPROFILE_SCOPE(OpenGL_VAO);
  103. auto [iter, is_cache_miss] = vertex_array_cache.try_emplace(regs.vertex_attrib_format);
  104. auto& vao_entry = iter->second;
  105. if (is_cache_miss) {
  106. vao_entry.Create();
  107. const GLuint vao = vao_entry.handle;
  108. // Eventhough we are using DSA to create this vertex array, there is a bug on Intel's blob
  109. // that fails to properly create the vertex array if it's not bound even after creating it
  110. // with glCreateVertexArrays
  111. state.draw.vertex_array = vao;
  112. state.ApplyVertexArrayState();
  113. // Use the vertex array as-is, assumes that the data is formatted correctly for OpenGL.
  114. // Enables the first 16 vertex attributes always, as we don't know which ones are actually
  115. // used until shader time. Note, Tegra technically supports 32, but we're capping this to 16
  116. // for now to avoid OpenGL errors.
  117. // TODO(Subv): Analyze the shader to identify which attributes are actually used and don't
  118. // assume every shader uses them all.
  119. for (u32 index = 0; index < 16; ++index) {
  120. const auto& attrib = regs.vertex_attrib_format[index];
  121. // Ignore invalid attributes.
  122. if (!attrib.IsValid())
  123. continue;
  124. const auto& buffer = regs.vertex_array[attrib.buffer];
  125. LOG_TRACE(Render_OpenGL,
  126. "vertex attrib {}, count={}, size={}, type={}, offset={}, normalize={}",
  127. index, attrib.ComponentCount(), attrib.SizeString(), attrib.TypeString(),
  128. attrib.offset.Value(), attrib.IsNormalized());
  129. ASSERT(buffer.IsEnabled());
  130. glEnableVertexArrayAttrib(vao, index);
  131. if (attrib.type == Tegra::Engines::Maxwell3D::Regs::VertexAttribute::Type::SignedInt ||
  132. attrib.type ==
  133. Tegra::Engines::Maxwell3D::Regs::VertexAttribute::Type::UnsignedInt) {
  134. glVertexArrayAttribIFormat(vao, index, attrib.ComponentCount(),
  135. MaxwellToGL::VertexType(attrib), attrib.offset);
  136. } else {
  137. glVertexArrayAttribFormat(
  138. vao, index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib),
  139. attrib.IsNormalized() ? GL_TRUE : GL_FALSE, attrib.offset);
  140. }
  141. glVertexArrayAttribBinding(vao, index, attrib.buffer);
  142. }
  143. }
  144. // Rebinding the VAO invalidates the vertex buffer bindings.
  145. gpu.dirty.ResetVertexArrays();
  146. state.draw.vertex_array = vao_entry.handle;
  147. return vao_entry.handle;
  148. }
  149. void RasterizerOpenGL::SetupVertexBuffer(GLuint vao) {
  150. auto& gpu = system.GPU().Maxwell3D();
  151. if (!gpu.dirty.vertex_array_buffers)
  152. return;
  153. gpu.dirty.vertex_array_buffers = false;
  154. const auto& regs = gpu.regs;
  155. MICROPROFILE_SCOPE(OpenGL_VB);
  156. // Upload all guest vertex arrays sequentially to our buffer
  157. for (u32 index = 0; index < Maxwell::NumVertexArrays; ++index) {
  158. if (!gpu.dirty.vertex_array[index])
  159. continue;
  160. gpu.dirty.vertex_array[index] = false;
  161. gpu.dirty.vertex_instance[index] = false;
  162. const auto& vertex_array = regs.vertex_array[index];
  163. if (!vertex_array.IsEnabled())
  164. continue;
  165. const GPUVAddr start = vertex_array.StartAddress();
  166. const GPUVAddr end = regs.vertex_array_limit[index].LimitAddress();
  167. ASSERT(end > start);
  168. const u64 size = end - start + 1;
  169. const auto [vertex_buffer, vertex_buffer_offset] = buffer_cache.UploadMemory(start, size);
  170. // Bind the vertex array to the buffer at the current offset.
  171. vertex_array_pushbuffer.SetVertexBuffer(index, vertex_buffer, vertex_buffer_offset,
  172. vertex_array.stride);
  173. if (regs.instanced_arrays.IsInstancingEnabled(index) && vertex_array.divisor != 0) {
  174. // Enable vertex buffer instancing with the specified divisor.
  175. glVertexArrayBindingDivisor(vao, index, vertex_array.divisor);
  176. } else {
  177. // Disable the vertex buffer instancing.
  178. glVertexArrayBindingDivisor(vao, index, 0);
  179. }
  180. }
  181. }
  182. void RasterizerOpenGL::SetupVertexInstances(GLuint vao) {
  183. auto& gpu = system.GPU().Maxwell3D();
  184. if (!gpu.dirty.vertex_instances)
  185. return;
  186. gpu.dirty.vertex_instances = false;
  187. const auto& regs = gpu.regs;
  188. // Upload all guest vertex arrays sequentially to our buffer
  189. for (u32 index = 0; index < Maxwell::NumVertexArrays; ++index) {
  190. if (!gpu.dirty.vertex_instance[index])
  191. continue;
  192. gpu.dirty.vertex_instance[index] = false;
  193. if (regs.instanced_arrays.IsInstancingEnabled(index) &&
  194. regs.vertex_array[index].divisor != 0) {
  195. // Enable vertex buffer instancing with the specified divisor.
  196. glVertexArrayBindingDivisor(vao, index, regs.vertex_array[index].divisor);
  197. } else {
  198. // Disable the vertex buffer instancing.
  199. glVertexArrayBindingDivisor(vao, index, 0);
  200. }
  201. }
  202. }
  203. GLintptr RasterizerOpenGL::SetupIndexBuffer() {
  204. if (accelerate_draw != AccelDraw::Indexed) {
  205. return 0;
  206. }
  207. MICROPROFILE_SCOPE(OpenGL_Index);
  208. const auto& regs = system.GPU().Maxwell3D().regs;
  209. const std::size_t size = CalculateIndexBufferSize();
  210. const auto [buffer, offset] = buffer_cache.UploadMemory(regs.index_array.IndexStart(), size);
  211. vertex_array_pushbuffer.SetIndexBuffer(buffer);
  212. return offset;
  213. }
  214. void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) {
  215. MICROPROFILE_SCOPE(OpenGL_Shader);
  216. auto& gpu = system.GPU().Maxwell3D();
  217. std::array<bool, Maxwell::NumClipDistances> clip_distances{};
  218. for (std::size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) {
  219. const auto& shader_config = gpu.regs.shader_config[index];
  220. const auto program{static_cast<Maxwell::ShaderProgram>(index)};
  221. // Skip stages that are not enabled
  222. if (!gpu.regs.IsShaderConfigEnabled(index)) {
  223. switch (program) {
  224. case Maxwell::ShaderProgram::Geometry:
  225. shader_program_manager->UseTrivialGeometryShader();
  226. break;
  227. case Maxwell::ShaderProgram::Fragment:
  228. shader_program_manager->UseTrivialFragmentShader();
  229. break;
  230. default:
  231. break;
  232. }
  233. continue;
  234. }
  235. // Currently this stages are not supported in the OpenGL backend.
  236. // Todo(Blinkhawk): Port tesselation shaders from Vulkan to OpenGL
  237. if (program == Maxwell::ShaderProgram::TesselationControl) {
  238. continue;
  239. } else if (program == Maxwell::ShaderProgram::TesselationEval) {
  240. continue;
  241. }
  242. Shader shader{shader_cache.GetStageProgram(program)};
  243. // Stage indices are 0 - 5
  244. const std::size_t stage = index == 0 ? 0 : index - 1;
  245. SetupDrawConstBuffers(stage, shader);
  246. SetupDrawGlobalMemory(stage, shader);
  247. SetupDrawTextures(stage, shader);
  248. SetupDrawImages(stage, shader);
  249. const ProgramVariant variant(primitive_mode);
  250. const auto program_handle = shader->GetHandle(variant);
  251. switch (program) {
  252. case Maxwell::ShaderProgram::VertexA:
  253. case Maxwell::ShaderProgram::VertexB:
  254. shader_program_manager->UseProgrammableVertexShader(program_handle);
  255. break;
  256. case Maxwell::ShaderProgram::Geometry:
  257. shader_program_manager->UseProgrammableGeometryShader(program_handle);
  258. break;
  259. case Maxwell::ShaderProgram::Fragment:
  260. shader_program_manager->UseProgrammableFragmentShader(program_handle);
  261. break;
  262. default:
  263. UNIMPLEMENTED_MSG("Unimplemented shader index={}, enable={}, offset=0x{:08X}", index,
  264. shader_config.enable.Value(), shader_config.offset);
  265. }
  266. // Workaround for Intel drivers.
  267. // When a clip distance is enabled but not set in the shader it crops parts of the screen
  268. // (sometimes it's half the screen, sometimes three quarters). To avoid this, enable the
  269. // clip distances only when it's written by a shader stage.
  270. for (std::size_t i = 0; i < Maxwell::NumClipDistances; ++i) {
  271. clip_distances[i] = clip_distances[i] || shader->GetShaderEntries().clip_distances[i];
  272. }
  273. // When VertexA is enabled, we have dual vertex shaders
  274. if (program == Maxwell::ShaderProgram::VertexA) {
  275. // VertexB was combined with VertexA, so we skip the VertexB iteration
  276. ++index;
  277. }
  278. }
  279. SyncClipEnabled(clip_distances);
  280. gpu.dirty.shaders = false;
  281. }
  282. std::size_t RasterizerOpenGL::CalculateVertexArraysSize() const {
  283. const auto& regs = system.GPU().Maxwell3D().regs;
  284. std::size_t size = 0;
  285. for (u32 index = 0; index < Maxwell::NumVertexArrays; ++index) {
  286. if (!regs.vertex_array[index].IsEnabled())
  287. continue;
  288. const GPUVAddr start = regs.vertex_array[index].StartAddress();
  289. const GPUVAddr end = regs.vertex_array_limit[index].LimitAddress();
  290. ASSERT(end > start);
  291. size += end - start + 1;
  292. }
  293. return size;
  294. }
  295. std::size_t RasterizerOpenGL::CalculateIndexBufferSize() const {
  296. const auto& regs = system.GPU().Maxwell3D().regs;
  297. return static_cast<std::size_t>(regs.index_array.count) *
  298. static_cast<std::size_t>(regs.index_array.FormatSizeInBytes());
  299. }
  300. void RasterizerOpenGL::LoadDiskResources(const std::atomic_bool& stop_loading,
  301. const VideoCore::DiskResourceLoadCallback& callback) {
  302. shader_cache.LoadDiskCache(stop_loading, callback);
  303. }
  304. void RasterizerOpenGL::ConfigureFramebuffers() {
  305. MICROPROFILE_SCOPE(OpenGL_Framebuffer);
  306. auto& gpu = system.GPU().Maxwell3D();
  307. if (!gpu.dirty.render_settings) {
  308. return;
  309. }
  310. gpu.dirty.render_settings = false;
  311. texture_cache.GuardRenderTargets(true);
  312. View depth_surface = texture_cache.GetDepthBufferSurface(true);
  313. const auto& regs = gpu.regs;
  314. state.framebuffer_srgb.enabled = regs.framebuffer_srgb != 0;
  315. UNIMPLEMENTED_IF(regs.rt_separate_frag_data == 0);
  316. // Bind the framebuffer surfaces
  317. FramebufferCacheKey key;
  318. const auto colors_count = static_cast<std::size_t>(regs.rt_control.count);
  319. for (std::size_t index = 0; index < colors_count; ++index) {
  320. View color_surface{texture_cache.GetColorBufferSurface(index, true)};
  321. if (!color_surface) {
  322. continue;
  323. }
  324. // Assume that a surface will be written to if it is used as a framebuffer, even
  325. // if the shader doesn't actually write to it.
  326. texture_cache.MarkColorBufferInUse(index);
  327. key.SetAttachment(index, regs.rt_control.GetMap(index));
  328. key.colors[index] = std::move(color_surface);
  329. }
  330. if (depth_surface) {
  331. // Assume that a surface will be written to if it is used as a framebuffer, even if
  332. // the shader doesn't actually write to it.
  333. texture_cache.MarkDepthBufferInUse();
  334. key.zeta = std::move(depth_surface);
  335. }
  336. texture_cache.GuardRenderTargets(false);
  337. state.draw.draw_framebuffer = framebuffer_cache.GetFramebuffer(key);
  338. SyncViewport(state);
  339. }
  340. void RasterizerOpenGL::ConfigureClearFramebuffer(OpenGLState& current_state, bool using_color_fb,
  341. bool using_depth_fb, bool using_stencil_fb) {
  342. using VideoCore::Surface::SurfaceType;
  343. auto& gpu = system.GPU().Maxwell3D();
  344. const auto& regs = gpu.regs;
  345. texture_cache.GuardRenderTargets(true);
  346. View color_surface;
  347. if (using_color_fb) {
  348. color_surface = texture_cache.GetColorBufferSurface(regs.clear_buffers.RT, false);
  349. }
  350. View depth_surface;
  351. if (using_depth_fb || using_stencil_fb) {
  352. depth_surface = texture_cache.GetDepthBufferSurface(false);
  353. }
  354. texture_cache.GuardRenderTargets(false);
  355. FramebufferCacheKey key;
  356. key.colors[0] = color_surface;
  357. key.zeta = depth_surface;
  358. current_state.draw.draw_framebuffer = framebuffer_cache.GetFramebuffer(key);
  359. current_state.ApplyFramebufferState();
  360. }
  361. void RasterizerOpenGL::Clear() {
  362. const auto& maxwell3d = system.GPU().Maxwell3D();
  363. if (!maxwell3d.ShouldExecute()) {
  364. return;
  365. }
  366. const auto& regs = maxwell3d.regs;
  367. bool use_color{};
  368. bool use_depth{};
  369. bool use_stencil{};
  370. OpenGLState prev_state{OpenGLState::GetCurState()};
  371. SCOPE_EXIT({
  372. prev_state.AllDirty();
  373. prev_state.Apply();
  374. });
  375. OpenGLState clear_state{OpenGLState::GetCurState()};
  376. clear_state.SetDefaultViewports();
  377. if (regs.clear_buffers.R || regs.clear_buffers.G || regs.clear_buffers.B ||
  378. regs.clear_buffers.A) {
  379. use_color = true;
  380. }
  381. if (use_color) {
  382. clear_state.color_mask[0].red_enabled = regs.clear_buffers.R ? GL_TRUE : GL_FALSE;
  383. clear_state.color_mask[0].green_enabled = regs.clear_buffers.G ? GL_TRUE : GL_FALSE;
  384. clear_state.color_mask[0].blue_enabled = regs.clear_buffers.B ? GL_TRUE : GL_FALSE;
  385. clear_state.color_mask[0].alpha_enabled = regs.clear_buffers.A ? GL_TRUE : GL_FALSE;
  386. }
  387. if (regs.clear_buffers.Z) {
  388. ASSERT_MSG(regs.zeta_enable != 0, "Tried to clear Z but buffer is not enabled!");
  389. use_depth = true;
  390. // Always enable the depth write when clearing the depth buffer. The depth write mask is
  391. // ignored when clearing the buffer in the Switch, but OpenGL obeys it so we set it to
  392. // true.
  393. clear_state.depth.test_enabled = true;
  394. clear_state.depth.test_func = GL_ALWAYS;
  395. clear_state.depth.write_mask = GL_TRUE;
  396. }
  397. if (regs.clear_buffers.S) {
  398. ASSERT_MSG(regs.zeta_enable != 0, "Tried to clear stencil but buffer is not enabled!");
  399. use_stencil = true;
  400. clear_state.stencil.test_enabled = true;
  401. if (regs.clear_flags.stencil) {
  402. // Stencil affects the clear so fill it with the used masks
  403. clear_state.stencil.front.test_func = GL_ALWAYS;
  404. clear_state.stencil.front.test_mask = regs.stencil_front_func_mask;
  405. clear_state.stencil.front.action_stencil_fail = GL_KEEP;
  406. clear_state.stencil.front.action_depth_fail = GL_KEEP;
  407. clear_state.stencil.front.action_depth_pass = GL_KEEP;
  408. clear_state.stencil.front.write_mask = regs.stencil_front_mask;
  409. if (regs.stencil_two_side_enable) {
  410. clear_state.stencil.back.test_func = GL_ALWAYS;
  411. clear_state.stencil.back.test_mask = regs.stencil_back_func_mask;
  412. clear_state.stencil.back.action_stencil_fail = GL_KEEP;
  413. clear_state.stencil.back.action_depth_fail = GL_KEEP;
  414. clear_state.stencil.back.action_depth_pass = GL_KEEP;
  415. clear_state.stencil.back.write_mask = regs.stencil_back_mask;
  416. } else {
  417. clear_state.stencil.back.test_func = GL_ALWAYS;
  418. clear_state.stencil.back.test_mask = 0xFFFFFFFF;
  419. clear_state.stencil.back.write_mask = 0xFFFFFFFF;
  420. clear_state.stencil.back.action_stencil_fail = GL_KEEP;
  421. clear_state.stencil.back.action_depth_fail = GL_KEEP;
  422. clear_state.stencil.back.action_depth_pass = GL_KEEP;
  423. }
  424. }
  425. }
  426. if (!use_color && !use_depth && !use_stencil) {
  427. // No color surface nor depth/stencil surface are enabled
  428. return;
  429. }
  430. ConfigureClearFramebuffer(clear_state, use_color, use_depth, use_stencil);
  431. SyncViewport(clear_state);
  432. SyncRasterizeEnable(clear_state);
  433. if (regs.clear_flags.scissor) {
  434. SyncScissorTest(clear_state);
  435. }
  436. if (regs.clear_flags.viewport) {
  437. clear_state.EmulateViewportWithScissor();
  438. }
  439. clear_state.AllDirty();
  440. clear_state.Apply();
  441. if (use_color) {
  442. glClearBufferfv(GL_COLOR, 0, regs.clear_color);
  443. }
  444. if (use_depth && use_stencil) {
  445. glClearBufferfi(GL_DEPTH_STENCIL, 0, regs.clear_depth, regs.clear_stencil);
  446. } else if (use_depth) {
  447. glClearBufferfv(GL_DEPTH, 0, &regs.clear_depth);
  448. } else if (use_stencil) {
  449. glClearBufferiv(GL_STENCIL, 0, &regs.clear_stencil);
  450. }
  451. }
  452. void RasterizerOpenGL::DrawPrelude() {
  453. auto& gpu = system.GPU().Maxwell3D();
  454. SyncRasterizeEnable(state);
  455. SyncColorMask();
  456. SyncFragmentColorClampState();
  457. SyncMultiSampleState();
  458. SyncDepthTestState();
  459. SyncStencilTestState();
  460. SyncBlendState();
  461. SyncLogicOpState();
  462. SyncCullMode();
  463. SyncPrimitiveRestart();
  464. SyncScissorTest(state);
  465. SyncTransformFeedback();
  466. SyncPointState();
  467. SyncPolygonOffset();
  468. SyncAlphaTest();
  469. buffer_cache.Acquire();
  470. // Draw the vertex batch
  471. const bool is_indexed = accelerate_draw == AccelDraw::Indexed;
  472. std::size_t buffer_size = CalculateVertexArraysSize();
  473. // Add space for index buffer
  474. if (is_indexed) {
  475. buffer_size = Common::AlignUp(buffer_size, 4) + CalculateIndexBufferSize();
  476. }
  477. // Uniform space for the 5 shader stages
  478. buffer_size = Common::AlignUp<std::size_t>(buffer_size, 4) +
  479. (sizeof(GLShader::MaxwellUniformData) + device.GetUniformBufferAlignment()) *
  480. Maxwell::MaxShaderStage;
  481. // Add space for at least 18 constant buffers
  482. buffer_size += Maxwell::MaxConstBuffers *
  483. (Maxwell::MaxConstBufferSize + device.GetUniformBufferAlignment());
  484. // Prepare the vertex array.
  485. buffer_cache.Map(buffer_size);
  486. // Prepare vertex array format.
  487. const GLuint vao = SetupVertexFormat();
  488. vertex_array_pushbuffer.Setup(vao);
  489. // Upload vertex and index data.
  490. SetupVertexBuffer(vao);
  491. SetupVertexInstances(vao);
  492. index_buffer_offset = SetupIndexBuffer();
  493. // Prepare packed bindings.
  494. bind_ubo_pushbuffer.Setup();
  495. bind_ssbo_pushbuffer.Setup();
  496. // Setup emulation uniform buffer.
  497. GLShader::MaxwellUniformData ubo;
  498. ubo.SetFromRegs(gpu);
  499. const auto [buffer, offset] =
  500. buffer_cache.UploadHostMemory(&ubo, sizeof(ubo), device.GetUniformBufferAlignment());
  501. bind_ubo_pushbuffer.Push(EmulationUniformBlockBinding, buffer, offset,
  502. static_cast<GLsizeiptr>(sizeof(ubo)));
  503. // Setup shaders and their used resources.
  504. texture_cache.GuardSamplers(true);
  505. const auto primitive_mode = MaxwellToGL::PrimitiveTopology(gpu.regs.draw.topology);
  506. SetupShaders(primitive_mode);
  507. texture_cache.GuardSamplers(false);
  508. ConfigureFramebuffers();
  509. // Signal the buffer cache that we are not going to upload more things.
  510. const bool invalidate = buffer_cache.Unmap();
  511. // Now that we are no longer uploading data, we can safely bind the buffers to OpenGL.
  512. vertex_array_pushbuffer.Bind();
  513. bind_ubo_pushbuffer.Bind();
  514. bind_ssbo_pushbuffer.Bind();
  515. if (invalidate) {
  516. // As all cached buffers are invalidated, we need to recheck their state.
  517. gpu.dirty.ResetVertexArrays();
  518. }
  519. shader_program_manager->ApplyTo(state);
  520. state.Apply();
  521. if (texture_cache.TextureBarrier()) {
  522. glTextureBarrier();
  523. }
  524. }
  525. struct DrawParams {
  526. bool is_indexed{};
  527. bool is_instanced{};
  528. GLenum primitive_mode{};
  529. GLint count{};
  530. GLint base_vertex{};
  531. // Indexed settings
  532. GLenum index_format{};
  533. GLintptr index_buffer_offset{};
  534. // Instanced setting
  535. GLint num_instances{};
  536. GLint base_instance{};
  537. void DispatchDraw() {
  538. if (is_indexed) {
  539. const auto index_buffer_ptr = reinterpret_cast<const void*>(index_buffer_offset);
  540. if (is_instanced) {
  541. glDrawElementsInstancedBaseVertexBaseInstance(primitive_mode, count, index_format,
  542. index_buffer_ptr, num_instances,
  543. base_vertex, base_instance);
  544. } else {
  545. glDrawElementsBaseVertex(primitive_mode, count, index_format, index_buffer_ptr,
  546. base_vertex);
  547. }
  548. } else {
  549. if (is_instanced) {
  550. glDrawArraysInstancedBaseInstance(primitive_mode, base_vertex, count, num_instances,
  551. base_instance);
  552. } else {
  553. glDrawArrays(primitive_mode, base_vertex, count);
  554. }
  555. }
  556. }
  557. };
  558. bool RasterizerOpenGL::DrawBatch(bool is_indexed) {
  559. accelerate_draw = is_indexed ? AccelDraw::Indexed : AccelDraw::Arrays;
  560. MICROPROFILE_SCOPE(OpenGL_Drawing);
  561. DrawPrelude();
  562. auto& maxwell3d = system.GPU().Maxwell3D();
  563. const auto& regs = maxwell3d.regs;
  564. const auto current_instance = maxwell3d.state.current_instance;
  565. DrawParams draw_call{};
  566. draw_call.is_indexed = is_indexed;
  567. draw_call.num_instances = static_cast<GLint>(1);
  568. draw_call.base_instance = static_cast<GLint>(current_instance);
  569. draw_call.is_instanced = current_instance > 0;
  570. draw_call.primitive_mode = MaxwellToGL::PrimitiveTopology(regs.draw.topology);
  571. if (draw_call.is_indexed) {
  572. draw_call.count = static_cast<GLint>(regs.index_array.count);
  573. draw_call.base_vertex = static_cast<GLint>(regs.vb_element_base);
  574. draw_call.index_format = MaxwellToGL::IndexFormat(regs.index_array.format);
  575. draw_call.index_buffer_offset = index_buffer_offset;
  576. } else {
  577. draw_call.count = static_cast<GLint>(regs.vertex_buffer.count);
  578. draw_call.base_vertex = static_cast<GLint>(regs.vertex_buffer.first);
  579. }
  580. draw_call.DispatchDraw();
  581. maxwell3d.dirty.memory_general = false;
  582. accelerate_draw = AccelDraw::Disabled;
  583. return true;
  584. }
  585. bool RasterizerOpenGL::DrawMultiBatch(bool is_indexed) {
  586. accelerate_draw = is_indexed ? AccelDraw::Indexed : AccelDraw::Arrays;
  587. MICROPROFILE_SCOPE(OpenGL_Drawing);
  588. DrawPrelude();
  589. auto& maxwell3d = system.GPU().Maxwell3D();
  590. const auto& regs = maxwell3d.regs;
  591. const auto& draw_setup = maxwell3d.mme_draw;
  592. DrawParams draw_call{};
  593. draw_call.is_indexed = is_indexed;
  594. draw_call.num_instances = static_cast<GLint>(draw_setup.instance_count);
  595. draw_call.base_instance = static_cast<GLint>(regs.vb_base_instance);
  596. draw_call.is_instanced = draw_setup.instance_count > 1;
  597. draw_call.primitive_mode = MaxwellToGL::PrimitiveTopology(regs.draw.topology);
  598. if (draw_call.is_indexed) {
  599. draw_call.count = static_cast<GLint>(regs.index_array.count);
  600. draw_call.base_vertex = static_cast<GLint>(regs.vb_element_base);
  601. draw_call.index_format = MaxwellToGL::IndexFormat(regs.index_array.format);
  602. draw_call.index_buffer_offset = index_buffer_offset;
  603. } else {
  604. draw_call.count = static_cast<GLint>(regs.vertex_buffer.count);
  605. draw_call.base_vertex = static_cast<GLint>(regs.vertex_buffer.first);
  606. }
  607. draw_call.DispatchDraw();
  608. maxwell3d.dirty.memory_general = false;
  609. accelerate_draw = AccelDraw::Disabled;
  610. return true;
  611. }
  612. void RasterizerOpenGL::DispatchCompute(GPUVAddr code_addr) {
  613. if (device.HasBrokenCompute()) {
  614. return;
  615. }
  616. buffer_cache.Acquire();
  617. auto kernel = shader_cache.GetComputeKernel(code_addr);
  618. SetupComputeTextures(kernel);
  619. SetupComputeImages(kernel);
  620. const auto& launch_desc = system.GPU().KeplerCompute().launch_description;
  621. const ProgramVariant variant(launch_desc.block_dim_x, launch_desc.block_dim_y,
  622. launch_desc.block_dim_z, launch_desc.shared_alloc,
  623. launch_desc.local_pos_alloc);
  624. state.draw.shader_program = kernel->GetHandle(variant);
  625. state.draw.program_pipeline = 0;
  626. const std::size_t buffer_size =
  627. Tegra::Engines::KeplerCompute::NumConstBuffers *
  628. (Maxwell::MaxConstBufferSize + device.GetUniformBufferAlignment());
  629. buffer_cache.Map(buffer_size);
  630. bind_ubo_pushbuffer.Setup();
  631. bind_ssbo_pushbuffer.Setup();
  632. SetupComputeConstBuffers(kernel);
  633. SetupComputeGlobalMemory(kernel);
  634. buffer_cache.Unmap();
  635. bind_ubo_pushbuffer.Bind();
  636. bind_ssbo_pushbuffer.Bind();
  637. state.ApplyTextures();
  638. state.ApplyImages();
  639. state.ApplyShaderProgram();
  640. state.ApplyProgramPipeline();
  641. glDispatchCompute(launch_desc.grid_dim_x, launch_desc.grid_dim_y, launch_desc.grid_dim_z);
  642. }
  643. void RasterizerOpenGL::FlushAll() {}
  644. void RasterizerOpenGL::FlushRegion(CacheAddr addr, u64 size) {
  645. MICROPROFILE_SCOPE(OpenGL_CacheManagement);
  646. if (!addr || !size) {
  647. return;
  648. }
  649. texture_cache.FlushRegion(addr, size);
  650. buffer_cache.FlushRegion(addr, size);
  651. }
  652. void RasterizerOpenGL::InvalidateRegion(CacheAddr addr, u64 size) {
  653. MICROPROFILE_SCOPE(OpenGL_CacheManagement);
  654. if (!addr || !size) {
  655. return;
  656. }
  657. texture_cache.InvalidateRegion(addr, size);
  658. shader_cache.InvalidateRegion(addr, size);
  659. buffer_cache.InvalidateRegion(addr, size);
  660. }
  661. void RasterizerOpenGL::FlushAndInvalidateRegion(CacheAddr addr, u64 size) {
  662. if (Settings::values.use_accurate_gpu_emulation) {
  663. FlushRegion(addr, size);
  664. }
  665. InvalidateRegion(addr, size);
  666. }
  667. void RasterizerOpenGL::FlushCommands() {
  668. glFlush();
  669. }
  670. void RasterizerOpenGL::TickFrame() {
  671. buffer_cache.TickFrame();
  672. }
  673. bool RasterizerOpenGL::AccelerateSurfaceCopy(const Tegra::Engines::Fermi2D::Regs::Surface& src,
  674. const Tegra::Engines::Fermi2D::Regs::Surface& dst,
  675. const Tegra::Engines::Fermi2D::Config& copy_config) {
  676. MICROPROFILE_SCOPE(OpenGL_Blits);
  677. texture_cache.DoFermiCopy(src, dst, copy_config);
  678. return true;
  679. }
  680. bool RasterizerOpenGL::AccelerateDisplay(const Tegra::FramebufferConfig& config,
  681. VAddr framebuffer_addr, u32 pixel_stride) {
  682. if (!framebuffer_addr) {
  683. return {};
  684. }
  685. MICROPROFILE_SCOPE(OpenGL_CacheManagement);
  686. const auto surface{
  687. texture_cache.TryFindFramebufferSurface(system.Memory().GetPointer(framebuffer_addr))};
  688. if (!surface) {
  689. return {};
  690. }
  691. // Verify that the cached surface is the same size and format as the requested framebuffer
  692. const auto& params{surface->GetSurfaceParams()};
  693. const auto& pixel_format{
  694. VideoCore::Surface::PixelFormatFromGPUPixelFormat(config.pixel_format)};
  695. ASSERT_MSG(params.width == config.width, "Framebuffer width is different");
  696. ASSERT_MSG(params.height == config.height, "Framebuffer height is different");
  697. if (params.pixel_format != pixel_format) {
  698. LOG_DEBUG(Render_OpenGL, "Framebuffer pixel_format is different");
  699. }
  700. screen_info.display_texture = surface->GetTexture();
  701. screen_info.display_srgb = surface->GetSurfaceParams().srgb_conversion;
  702. return true;
  703. }
  704. void RasterizerOpenGL::SetupDrawConstBuffers(std::size_t stage_index, const Shader& shader) {
  705. MICROPROFILE_SCOPE(OpenGL_UBO);
  706. const auto& stages = system.GPU().Maxwell3D().state.shader_stages;
  707. const auto& shader_stage = stages[stage_index];
  708. u32 binding = device.GetBaseBindings(stage_index).uniform_buffer;
  709. for (const auto& entry : shader->GetShaderEntries().const_buffers) {
  710. const auto& buffer = shader_stage.const_buffers[entry.GetIndex()];
  711. SetupConstBuffer(binding++, buffer, entry);
  712. }
  713. }
  714. void RasterizerOpenGL::SetupComputeConstBuffers(const Shader& kernel) {
  715. MICROPROFILE_SCOPE(OpenGL_UBO);
  716. const auto& launch_desc = system.GPU().KeplerCompute().launch_description;
  717. u32 binding = 0;
  718. for (const auto& entry : kernel->GetShaderEntries().const_buffers) {
  719. const auto& config = launch_desc.const_buffer_config[entry.GetIndex()];
  720. const std::bitset<8> mask = launch_desc.const_buffer_enable_mask.Value();
  721. Tegra::Engines::ConstBufferInfo buffer;
  722. buffer.address = config.Address();
  723. buffer.size = config.size;
  724. buffer.enabled = mask[entry.GetIndex()];
  725. SetupConstBuffer(binding++, buffer, entry);
  726. }
  727. }
  728. void RasterizerOpenGL::SetupConstBuffer(u32 binding, const Tegra::Engines::ConstBufferInfo& buffer,
  729. const GLShader::ConstBufferEntry& entry) {
  730. if (!buffer.enabled) {
  731. // Set values to zero to unbind buffers
  732. bind_ubo_pushbuffer.Push(binding, buffer_cache.GetEmptyBuffer(sizeof(float)), 0,
  733. sizeof(float));
  734. return;
  735. }
  736. // Align the actual size so it ends up being a multiple of vec4 to meet the OpenGL std140
  737. // UBO alignment requirements.
  738. const std::size_t size = Common::AlignUp(GetConstBufferSize(buffer, entry), sizeof(GLvec4));
  739. const auto alignment = device.GetUniformBufferAlignment();
  740. const auto [cbuf, offset] = buffer_cache.UploadMemory(buffer.address, size, alignment, false,
  741. device.HasFastBufferSubData());
  742. bind_ubo_pushbuffer.Push(binding, cbuf, offset, size);
  743. }
  744. void RasterizerOpenGL::SetupDrawGlobalMemory(std::size_t stage_index, const Shader& shader) {
  745. auto& gpu{system.GPU()};
  746. auto& memory_manager{gpu.MemoryManager()};
  747. const auto cbufs{gpu.Maxwell3D().state.shader_stages[stage_index]};
  748. u32 binding = device.GetBaseBindings(stage_index).shader_storage_buffer;
  749. for (const auto& entry : shader->GetShaderEntries().global_memory_entries) {
  750. const auto addr{cbufs.const_buffers[entry.GetCbufIndex()].address + entry.GetCbufOffset()};
  751. const auto gpu_addr{memory_manager.Read<u64>(addr)};
  752. const auto size{memory_manager.Read<u32>(addr + 8)};
  753. SetupGlobalMemory(binding++, entry, gpu_addr, size);
  754. }
  755. }
  756. void RasterizerOpenGL::SetupComputeGlobalMemory(const Shader& kernel) {
  757. auto& gpu{system.GPU()};
  758. auto& memory_manager{gpu.MemoryManager()};
  759. const auto cbufs{gpu.KeplerCompute().launch_description.const_buffer_config};
  760. u32 binding = 0;
  761. for (const auto& entry : kernel->GetShaderEntries().global_memory_entries) {
  762. const auto addr{cbufs[entry.GetCbufIndex()].Address() + entry.GetCbufOffset()};
  763. const auto gpu_addr{memory_manager.Read<u64>(addr)};
  764. const auto size{memory_manager.Read<u32>(addr + 8)};
  765. SetupGlobalMemory(binding++, entry, gpu_addr, size);
  766. }
  767. }
  768. void RasterizerOpenGL::SetupGlobalMemory(u32 binding, const GLShader::GlobalMemoryEntry& entry,
  769. GPUVAddr gpu_addr, std::size_t size) {
  770. const auto alignment{device.GetShaderStorageBufferAlignment()};
  771. const auto [ssbo, buffer_offset] =
  772. buffer_cache.UploadMemory(gpu_addr, size, alignment, entry.IsWritten());
  773. bind_ssbo_pushbuffer.Push(binding, ssbo, buffer_offset, static_cast<GLsizeiptr>(size));
  774. }
  775. void RasterizerOpenGL::SetupDrawTextures(std::size_t stage_index, const Shader& shader) {
  776. MICROPROFILE_SCOPE(OpenGL_Texture);
  777. const auto& maxwell3d = system.GPU().Maxwell3D();
  778. u32 binding = device.GetBaseBindings(stage_index).sampler;
  779. for (const auto& entry : shader->GetShaderEntries().samplers) {
  780. const auto shader_type = static_cast<Tegra::Engines::ShaderType>(stage_index);
  781. const auto texture = GetTextureInfo(maxwell3d, entry, shader_type);
  782. SetupTexture(binding++, texture, entry);
  783. }
  784. }
  785. void RasterizerOpenGL::SetupComputeTextures(const Shader& kernel) {
  786. MICROPROFILE_SCOPE(OpenGL_Texture);
  787. const auto& compute = system.GPU().KeplerCompute();
  788. u32 binding = 0;
  789. for (const auto& entry : kernel->GetShaderEntries().samplers) {
  790. const auto texture = GetTextureInfo(compute, entry, Tegra::Engines::ShaderType::Compute);
  791. SetupTexture(binding++, texture, entry);
  792. }
  793. }
  794. void RasterizerOpenGL::SetupTexture(u32 binding, const Tegra::Texture::FullTextureInfo& texture,
  795. const GLShader::SamplerEntry& entry) {
  796. const auto view = texture_cache.GetTextureSurface(texture.tic, entry);
  797. if (!view) {
  798. // Can occur when texture addr is null or its memory is unmapped/invalid
  799. state.samplers[binding] = 0;
  800. state.textures[binding] = 0;
  801. return;
  802. }
  803. state.textures[binding] = view->GetTexture();
  804. if (view->GetSurfaceParams().IsBuffer()) {
  805. return;
  806. }
  807. state.samplers[binding] = sampler_cache.GetSampler(texture.tsc);
  808. // Apply swizzle to textures that are not buffers.
  809. view->ApplySwizzle(texture.tic.x_source, texture.tic.y_source, texture.tic.z_source,
  810. texture.tic.w_source);
  811. }
  812. void RasterizerOpenGL::SetupDrawImages(std::size_t stage_index, const Shader& shader) {
  813. const auto& maxwell3d = system.GPU().Maxwell3D();
  814. u32 binding = device.GetBaseBindings(stage_index).image;
  815. for (const auto& entry : shader->GetShaderEntries().images) {
  816. const auto shader_type = static_cast<Tegra::Engines::ShaderType>(stage_index);
  817. const auto tic = GetTextureInfo(maxwell3d, entry, shader_type).tic;
  818. SetupImage(binding++, tic, entry);
  819. }
  820. }
  821. void RasterizerOpenGL::SetupComputeImages(const Shader& shader) {
  822. const auto& compute = system.GPU().KeplerCompute();
  823. u32 binding = 0;
  824. for (const auto& entry : shader->GetShaderEntries().images) {
  825. const auto tic = GetTextureInfo(compute, entry, Tegra::Engines::ShaderType::Compute).tic;
  826. SetupImage(binding++, tic, entry);
  827. }
  828. }
  829. void RasterizerOpenGL::SetupImage(u32 binding, const Tegra::Texture::TICEntry& tic,
  830. const GLShader::ImageEntry& entry) {
  831. const auto view = texture_cache.GetImageSurface(tic, entry);
  832. if (!view) {
  833. state.images[binding] = 0;
  834. return;
  835. }
  836. if (!tic.IsBuffer()) {
  837. view->ApplySwizzle(tic.x_source, tic.y_source, tic.z_source, tic.w_source);
  838. }
  839. if (entry.IsWritten()) {
  840. view->MarkAsModified(texture_cache.Tick());
  841. }
  842. state.images[binding] = view->GetTexture();
  843. }
  844. void RasterizerOpenGL::SyncViewport(OpenGLState& current_state) {
  845. const auto& regs = system.GPU().Maxwell3D().regs;
  846. const bool geometry_shaders_enabled =
  847. regs.IsShaderConfigEnabled(static_cast<size_t>(Maxwell::ShaderProgram::Geometry));
  848. const std::size_t viewport_count =
  849. geometry_shaders_enabled ? Tegra::Engines::Maxwell3D::Regs::NumViewports : 1;
  850. for (std::size_t i = 0; i < viewport_count; i++) {
  851. auto& viewport = current_state.viewports[i];
  852. const auto& src = regs.viewports[i];
  853. const Common::Rectangle<s32> viewport_rect{regs.viewport_transform[i].GetRect()};
  854. viewport.x = viewport_rect.left;
  855. viewport.y = viewport_rect.bottom;
  856. viewport.width = viewport_rect.GetWidth();
  857. viewport.height = viewport_rect.GetHeight();
  858. viewport.depth_range_far = src.depth_range_far;
  859. viewport.depth_range_near = src.depth_range_near;
  860. }
  861. state.depth_clamp.far_plane = regs.view_volume_clip_control.depth_clamp_far != 0;
  862. state.depth_clamp.near_plane = regs.view_volume_clip_control.depth_clamp_near != 0;
  863. bool flip_y = false;
  864. if (regs.viewport_transform[0].scale_y < 0.0) {
  865. flip_y = !flip_y;
  866. }
  867. if (regs.screen_y_control.y_negate != 0) {
  868. flip_y = !flip_y;
  869. }
  870. state.clip_control.origin = flip_y ? GL_UPPER_LEFT : GL_LOWER_LEFT;
  871. state.clip_control.depth_mode =
  872. regs.depth_mode == Tegra::Engines::Maxwell3D::Regs::DepthMode::ZeroToOne
  873. ? GL_ZERO_TO_ONE
  874. : GL_NEGATIVE_ONE_TO_ONE;
  875. }
  876. void RasterizerOpenGL::SyncClipEnabled(
  877. const std::array<bool, Maxwell::Regs::NumClipDistances>& clip_mask) {
  878. const auto& regs = system.GPU().Maxwell3D().regs;
  879. const std::array<bool, Maxwell::Regs::NumClipDistances> reg_state{
  880. regs.clip_distance_enabled.c0 != 0, regs.clip_distance_enabled.c1 != 0,
  881. regs.clip_distance_enabled.c2 != 0, regs.clip_distance_enabled.c3 != 0,
  882. regs.clip_distance_enabled.c4 != 0, regs.clip_distance_enabled.c5 != 0,
  883. regs.clip_distance_enabled.c6 != 0, regs.clip_distance_enabled.c7 != 0};
  884. for (std::size_t i = 0; i < Maxwell::Regs::NumClipDistances; ++i) {
  885. state.clip_distance[i] = reg_state[i] && clip_mask[i];
  886. }
  887. }
  888. void RasterizerOpenGL::SyncClipCoef() {
  889. UNIMPLEMENTED();
  890. }
  891. void RasterizerOpenGL::SyncCullMode() {
  892. const auto& regs = system.GPU().Maxwell3D().regs;
  893. state.cull.enabled = regs.cull.enabled != 0;
  894. if (state.cull.enabled) {
  895. state.cull.mode = MaxwellToGL::CullFace(regs.cull.cull_face);
  896. }
  897. state.cull.front_face = MaxwellToGL::FrontFace(regs.cull.front_face);
  898. }
  899. void RasterizerOpenGL::SyncPrimitiveRestart() {
  900. const auto& regs = system.GPU().Maxwell3D().regs;
  901. state.primitive_restart.enabled = regs.primitive_restart.enabled;
  902. state.primitive_restart.index = regs.primitive_restart.index;
  903. }
  904. void RasterizerOpenGL::SyncDepthTestState() {
  905. const auto& regs = system.GPU().Maxwell3D().regs;
  906. state.depth.test_enabled = regs.depth_test_enable != 0;
  907. state.depth.write_mask = regs.depth_write_enabled ? GL_TRUE : GL_FALSE;
  908. if (!state.depth.test_enabled) {
  909. return;
  910. }
  911. state.depth.test_func = MaxwellToGL::ComparisonOp(regs.depth_test_func);
  912. }
  913. void RasterizerOpenGL::SyncStencilTestState() {
  914. auto& maxwell3d = system.GPU().Maxwell3D();
  915. if (!maxwell3d.dirty.stencil_test) {
  916. return;
  917. }
  918. maxwell3d.dirty.stencil_test = false;
  919. const auto& regs = maxwell3d.regs;
  920. state.stencil.test_enabled = regs.stencil_enable != 0;
  921. state.MarkDirtyStencilState();
  922. if (!regs.stencil_enable) {
  923. return;
  924. }
  925. state.stencil.front.test_func = MaxwellToGL::ComparisonOp(regs.stencil_front_func_func);
  926. state.stencil.front.test_ref = regs.stencil_front_func_ref;
  927. state.stencil.front.test_mask = regs.stencil_front_func_mask;
  928. state.stencil.front.action_stencil_fail = MaxwellToGL::StencilOp(regs.stencil_front_op_fail);
  929. state.stencil.front.action_depth_fail = MaxwellToGL::StencilOp(regs.stencil_front_op_zfail);
  930. state.stencil.front.action_depth_pass = MaxwellToGL::StencilOp(regs.stencil_front_op_zpass);
  931. state.stencil.front.write_mask = regs.stencil_front_mask;
  932. if (regs.stencil_two_side_enable) {
  933. state.stencil.back.test_func = MaxwellToGL::ComparisonOp(regs.stencil_back_func_func);
  934. state.stencil.back.test_ref = regs.stencil_back_func_ref;
  935. state.stencil.back.test_mask = regs.stencil_back_func_mask;
  936. state.stencil.back.action_stencil_fail = MaxwellToGL::StencilOp(regs.stencil_back_op_fail);
  937. state.stencil.back.action_depth_fail = MaxwellToGL::StencilOp(regs.stencil_back_op_zfail);
  938. state.stencil.back.action_depth_pass = MaxwellToGL::StencilOp(regs.stencil_back_op_zpass);
  939. state.stencil.back.write_mask = regs.stencil_back_mask;
  940. } else {
  941. state.stencil.back.test_func = GL_ALWAYS;
  942. state.stencil.back.test_ref = 0;
  943. state.stencil.back.test_mask = 0xFFFFFFFF;
  944. state.stencil.back.write_mask = 0xFFFFFFFF;
  945. state.stencil.back.action_stencil_fail = GL_KEEP;
  946. state.stencil.back.action_depth_fail = GL_KEEP;
  947. state.stencil.back.action_depth_pass = GL_KEEP;
  948. }
  949. }
  950. void RasterizerOpenGL::SyncRasterizeEnable(OpenGLState& current_state) {
  951. const auto& regs = system.GPU().Maxwell3D().regs;
  952. current_state.rasterizer_discard = regs.rasterize_enable == 0;
  953. }
  954. void RasterizerOpenGL::SyncColorMask() {
  955. auto& maxwell3d = system.GPU().Maxwell3D();
  956. if (!maxwell3d.dirty.color_mask) {
  957. return;
  958. }
  959. const auto& regs = maxwell3d.regs;
  960. const std::size_t count =
  961. regs.independent_blend_enable ? Tegra::Engines::Maxwell3D::Regs::NumRenderTargets : 1;
  962. for (std::size_t i = 0; i < count; i++) {
  963. const auto& source = regs.color_mask[regs.color_mask_common ? 0 : i];
  964. auto& dest = state.color_mask[i];
  965. dest.red_enabled = (source.R == 0) ? GL_FALSE : GL_TRUE;
  966. dest.green_enabled = (source.G == 0) ? GL_FALSE : GL_TRUE;
  967. dest.blue_enabled = (source.B == 0) ? GL_FALSE : GL_TRUE;
  968. dest.alpha_enabled = (source.A == 0) ? GL_FALSE : GL_TRUE;
  969. }
  970. state.MarkDirtyColorMask();
  971. maxwell3d.dirty.color_mask = false;
  972. }
  973. void RasterizerOpenGL::SyncMultiSampleState() {
  974. const auto& regs = system.GPU().Maxwell3D().regs;
  975. state.multisample_control.alpha_to_coverage = regs.multisample_control.alpha_to_coverage != 0;
  976. state.multisample_control.alpha_to_one = regs.multisample_control.alpha_to_one != 0;
  977. }
  978. void RasterizerOpenGL::SyncFragmentColorClampState() {
  979. const auto& regs = system.GPU().Maxwell3D().regs;
  980. state.fragment_color_clamp.enabled = regs.frag_color_clamp != 0;
  981. }
  982. void RasterizerOpenGL::SyncBlendState() {
  983. auto& maxwell3d = system.GPU().Maxwell3D();
  984. if (!maxwell3d.dirty.blend_state) {
  985. return;
  986. }
  987. const auto& regs = maxwell3d.regs;
  988. state.blend_color.red = regs.blend_color.r;
  989. state.blend_color.green = regs.blend_color.g;
  990. state.blend_color.blue = regs.blend_color.b;
  991. state.blend_color.alpha = regs.blend_color.a;
  992. state.independant_blend.enabled = regs.independent_blend_enable;
  993. if (!state.independant_blend.enabled) {
  994. auto& blend = state.blend[0];
  995. const auto& src = regs.blend;
  996. blend.enabled = src.enable[0] != 0;
  997. if (blend.enabled) {
  998. blend.rgb_equation = MaxwellToGL::BlendEquation(src.equation_rgb);
  999. blend.src_rgb_func = MaxwellToGL::BlendFunc(src.factor_source_rgb);
  1000. blend.dst_rgb_func = MaxwellToGL::BlendFunc(src.factor_dest_rgb);
  1001. blend.a_equation = MaxwellToGL::BlendEquation(src.equation_a);
  1002. blend.src_a_func = MaxwellToGL::BlendFunc(src.factor_source_a);
  1003. blend.dst_a_func = MaxwellToGL::BlendFunc(src.factor_dest_a);
  1004. }
  1005. for (std::size_t i = 1; i < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets; i++) {
  1006. state.blend[i].enabled = false;
  1007. }
  1008. maxwell3d.dirty.blend_state = false;
  1009. state.MarkDirtyBlendState();
  1010. return;
  1011. }
  1012. for (std::size_t i = 0; i < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets; i++) {
  1013. auto& blend = state.blend[i];
  1014. const auto& src = regs.independent_blend[i];
  1015. blend.enabled = regs.blend.enable[i] != 0;
  1016. if (!blend.enabled)
  1017. continue;
  1018. blend.rgb_equation = MaxwellToGL::BlendEquation(src.equation_rgb);
  1019. blend.src_rgb_func = MaxwellToGL::BlendFunc(src.factor_source_rgb);
  1020. blend.dst_rgb_func = MaxwellToGL::BlendFunc(src.factor_dest_rgb);
  1021. blend.a_equation = MaxwellToGL::BlendEquation(src.equation_a);
  1022. blend.src_a_func = MaxwellToGL::BlendFunc(src.factor_source_a);
  1023. blend.dst_a_func = MaxwellToGL::BlendFunc(src.factor_dest_a);
  1024. }
  1025. state.MarkDirtyBlendState();
  1026. maxwell3d.dirty.blend_state = false;
  1027. }
  1028. void RasterizerOpenGL::SyncLogicOpState() {
  1029. const auto& regs = system.GPU().Maxwell3D().regs;
  1030. state.logic_op.enabled = regs.logic_op.enable != 0;
  1031. if (!state.logic_op.enabled)
  1032. return;
  1033. ASSERT_MSG(regs.blend.enable[0] == 0,
  1034. "Blending and logic op can't be enabled at the same time.");
  1035. state.logic_op.operation = MaxwellToGL::LogicOp(regs.logic_op.operation);
  1036. }
  1037. void RasterizerOpenGL::SyncScissorTest(OpenGLState& current_state) {
  1038. const auto& regs = system.GPU().Maxwell3D().regs;
  1039. const bool geometry_shaders_enabled =
  1040. regs.IsShaderConfigEnabled(static_cast<size_t>(Maxwell::ShaderProgram::Geometry));
  1041. const std::size_t viewport_count =
  1042. geometry_shaders_enabled ? Tegra::Engines::Maxwell3D::Regs::NumViewports : 1;
  1043. for (std::size_t i = 0; i < viewport_count; i++) {
  1044. const auto& src = regs.scissor_test[i];
  1045. auto& dst = current_state.viewports[i].scissor;
  1046. dst.enabled = (src.enable != 0);
  1047. if (dst.enabled == 0) {
  1048. return;
  1049. }
  1050. const u32 width = src.max_x - src.min_x;
  1051. const u32 height = src.max_y - src.min_y;
  1052. dst.x = src.min_x;
  1053. dst.y = src.min_y;
  1054. dst.width = width;
  1055. dst.height = height;
  1056. }
  1057. }
  1058. void RasterizerOpenGL::SyncTransformFeedback() {
  1059. const auto& regs = system.GPU().Maxwell3D().regs;
  1060. UNIMPLEMENTED_IF_MSG(regs.tfb_enabled != 0, "Transform feedbacks are not implemented");
  1061. }
  1062. void RasterizerOpenGL::SyncPointState() {
  1063. const auto& regs = system.GPU().Maxwell3D().regs;
  1064. // Limit the point size to 1 since nouveau sometimes sets a point size of 0 (and that's invalid
  1065. // in OpenGL).
  1066. state.point.program_control = regs.vp_point_size.enable != 0;
  1067. state.point.size = std::max(1.0f, regs.point_size);
  1068. }
  1069. void RasterizerOpenGL::SyncPolygonOffset() {
  1070. auto& maxwell3d = system.GPU().Maxwell3D();
  1071. if (!maxwell3d.dirty.polygon_offset) {
  1072. return;
  1073. }
  1074. const auto& regs = maxwell3d.regs;
  1075. state.polygon_offset.fill_enable = regs.polygon_offset_fill_enable != 0;
  1076. state.polygon_offset.line_enable = regs.polygon_offset_line_enable != 0;
  1077. state.polygon_offset.point_enable = regs.polygon_offset_point_enable != 0;
  1078. // Hardware divides polygon offset units by two
  1079. state.polygon_offset.units = regs.polygon_offset_units / 2.0f;
  1080. state.polygon_offset.factor = regs.polygon_offset_factor;
  1081. state.polygon_offset.clamp = regs.polygon_offset_clamp;
  1082. state.MarkDirtyPolygonOffset();
  1083. maxwell3d.dirty.polygon_offset = false;
  1084. }
  1085. void RasterizerOpenGL::SyncAlphaTest() {
  1086. const auto& regs = system.GPU().Maxwell3D().regs;
  1087. UNIMPLEMENTED_IF_MSG(regs.alpha_test_enabled != 0 && regs.rt_control.count > 1,
  1088. "Alpha Testing is enabled with more than one rendertarget");
  1089. state.alpha_test.enabled = regs.alpha_test_enabled;
  1090. if (!state.alpha_test.enabled) {
  1091. return;
  1092. }
  1093. state.alpha_test.func = MaxwellToGL::ComparisonOp(regs.alpha_test_func);
  1094. state.alpha_test.ref = regs.alpha_test_ref;
  1095. }
  1096. } // namespace OpenGL