gl_rasterizer.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. // Copyright 2015 Citra Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include <memory>
  5. #include <string>
  6. #include <tuple>
  7. #include <utility>
  8. #include <glad/glad.h>
  9. #include "common/alignment.h"
  10. #include "common/assert.h"
  11. #include "common/logging/log.h"
  12. #include "common/math_util.h"
  13. #include "common/microprofile.h"
  14. #include "common/scope_exit.h"
  15. #include "common/vector_math.h"
  16. #include "core/settings.h"
  17. #include "video_core/renderer_opengl/gl_rasterizer.h"
  18. #include "video_core/renderer_opengl/gl_shader_gen.h"
  19. #include "video_core/renderer_opengl/renderer_opengl.h"
  20. using PixelFormat = SurfaceParams::PixelFormat;
  21. using SurfaceType = SurfaceParams::SurfaceType;
  22. MICROPROFILE_DEFINE(OpenGL_VAO, "OpenGL", "Vertex Array Setup", MP_RGB(128, 128, 192));
  23. MICROPROFILE_DEFINE(OpenGL_VS, "OpenGL", "Vertex Shader Setup", MP_RGB(128, 128, 192));
  24. MICROPROFILE_DEFINE(OpenGL_FS, "OpenGL", "Fragment Shader Setup", MP_RGB(128, 128, 192));
  25. MICROPROFILE_DEFINE(OpenGL_Drawing, "OpenGL", "Drawing", MP_RGB(128, 128, 192));
  26. MICROPROFILE_DEFINE(OpenGL_Blits, "OpenGL", "Blits", MP_RGB(100, 100, 255));
  27. MICROPROFILE_DEFINE(OpenGL_CacheManagement, "OpenGL", "Cache Mgmt", MP_RGB(100, 255, 100));
  28. enum class UniformBindings : GLuint { Common, VS, FS };
  29. static void SetShaderUniformBlockBinding(GLuint shader, const char* name, UniformBindings binding,
  30. size_t expected_size) {
  31. GLuint ub_index = glGetUniformBlockIndex(shader, name);
  32. if (ub_index != GL_INVALID_INDEX) {
  33. GLint ub_size = 0;
  34. glGetActiveUniformBlockiv(shader, ub_index, GL_UNIFORM_BLOCK_DATA_SIZE, &ub_size);
  35. ASSERT_MSG(ub_size == expected_size,
  36. "Uniform block size did not match! Got %d, expected %zu",
  37. static_cast<int>(ub_size), expected_size);
  38. glUniformBlockBinding(shader, ub_index, static_cast<GLuint>(binding));
  39. }
  40. }
  41. static void SetShaderUniformBlockBindings(GLuint shader) {
  42. SetShaderUniformBlockBinding(shader, "shader_data", UniformBindings::Common,
  43. sizeof(RasterizerOpenGL::UniformData));
  44. SetShaderUniformBlockBinding(shader, "vs_config", UniformBindings::VS,
  45. sizeof(RasterizerOpenGL::VSUniformData));
  46. SetShaderUniformBlockBinding(shader, "fs_config", UniformBindings::FS,
  47. sizeof(RasterizerOpenGL::FSUniformData));
  48. }
  49. RasterizerOpenGL::RasterizerOpenGL() {
  50. shader_dirty = true;
  51. has_ARB_buffer_storage = false;
  52. has_ARB_direct_state_access = false;
  53. has_ARB_separate_shader_objects = false;
  54. has_ARB_vertex_attrib_binding = false;
  55. GLint ext_num;
  56. glGetIntegerv(GL_NUM_EXTENSIONS, &ext_num);
  57. for (GLint i = 0; i < ext_num; i++) {
  58. std::string extension{reinterpret_cast<const char*>(glGetStringi(GL_EXTENSIONS, i))};
  59. if (extension == "GL_ARB_buffer_storage") {
  60. has_ARB_buffer_storage = true;
  61. } else if (extension == "GL_ARB_direct_state_access") {
  62. has_ARB_direct_state_access = true;
  63. } else if (extension == "GL_ARB_separate_shader_objects") {
  64. has_ARB_separate_shader_objects = true;
  65. } else if (extension == "GL_ARB_vertex_attrib_binding") {
  66. has_ARB_vertex_attrib_binding = true;
  67. }
  68. }
  69. // Clipping plane 0 is always enabled for PICA fixed clip plane z <= 0
  70. state.clip_distance[0] = true;
  71. // Generate VBO, VAO and UBO
  72. vertex_buffer = OGLStreamBuffer::MakeBuffer(GLAD_GL_ARB_buffer_storage, GL_ARRAY_BUFFER);
  73. vertex_buffer->Create(VERTEX_BUFFER_SIZE, VERTEX_BUFFER_SIZE / 2);
  74. sw_vao.Create();
  75. uniform_buffer.Create();
  76. state.draw.vertex_array = sw_vao.handle;
  77. state.draw.vertex_buffer = vertex_buffer->GetHandle();
  78. state.draw.uniform_buffer = uniform_buffer.handle;
  79. state.Apply();
  80. glBufferData(GL_UNIFORM_BUFFER, sizeof(UniformData), nullptr, GL_STATIC_DRAW);
  81. glBindBufferBase(GL_UNIFORM_BUFFER, 0, uniform_buffer.handle);
  82. uniform_block_data.dirty = true;
  83. // Create render framebuffer
  84. framebuffer.Create();
  85. if (has_ARB_separate_shader_objects) {
  86. hw_vao.Create();
  87. hw_vao_enabled_attributes.fill(false);
  88. stream_buffer = OGLStreamBuffer::MakeBuffer(has_ARB_buffer_storage, GL_ARRAY_BUFFER);
  89. stream_buffer->Create(STREAM_BUFFER_SIZE, STREAM_BUFFER_SIZE / 2);
  90. state.draw.vertex_buffer = stream_buffer->GetHandle();
  91. pipeline.Create();
  92. state.draw.program_pipeline = pipeline.handle;
  93. state.draw.shader_program = 0;
  94. state.draw.vertex_array = hw_vao.handle;
  95. state.Apply();
  96. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, stream_buffer->GetHandle());
  97. vs_uniform_buffer.Create();
  98. glBindBuffer(GL_UNIFORM_BUFFER, vs_uniform_buffer.handle);
  99. glBufferData(GL_UNIFORM_BUFFER, sizeof(VSUniformData), nullptr, GL_STREAM_COPY);
  100. glBindBufferBase(GL_UNIFORM_BUFFER, 1, vs_uniform_buffer.handle);
  101. } else {
  102. ASSERT_MSG(false, "Unimplemented");
  103. }
  104. accelerate_draw = AccelDraw::Disabled;
  105. glEnable(GL_BLEND);
  106. LOG_WARNING(HW_GPU, "Sync fixed function OpenGL state here when ready");
  107. }
  108. RasterizerOpenGL::~RasterizerOpenGL() {
  109. if (stream_buffer != nullptr) {
  110. state.draw.vertex_buffer = stream_buffer->GetHandle();
  111. state.Apply();
  112. stream_buffer->Release();
  113. }
  114. }
  115. static constexpr std::array<GLenum, 4> vs_attrib_types{
  116. GL_BYTE, // VertexAttributeFormat::BYTE
  117. GL_UNSIGNED_BYTE, // VertexAttributeFormat::UBYTE
  118. GL_SHORT, // VertexAttributeFormat::SHORT
  119. GL_FLOAT // VertexAttributeFormat::FLOAT
  120. };
  121. void RasterizerOpenGL::AnalyzeVertexArray(bool is_indexed) {
  122. UNIMPLEMENTED();
  123. }
  124. void RasterizerOpenGL::SetupVertexArray(u8* array_ptr, GLintptr buffer_offset) {
  125. MICROPROFILE_SCOPE(OpenGL_VAO);
  126. UNIMPLEMENTED();
  127. }
  128. void RasterizerOpenGL::SetupVertexShader(VSUniformData* ub_ptr, GLintptr buffer_offset) {
  129. MICROPROFILE_SCOPE(OpenGL_VS);
  130. UNIMPLEMENTED();
  131. }
  132. void RasterizerOpenGL::SetupFragmentShader(FSUniformData* ub_ptr, GLintptr buffer_offset) {
  133. MICROPROFILE_SCOPE(OpenGL_FS);
  134. ASSERT_MSG(false, "Unimplemented");
  135. }
  136. bool RasterizerOpenGL::AccelerateDrawBatch(bool is_indexed) {
  137. if (!has_ARB_separate_shader_objects) {
  138. ASSERT_MSG(false, "Unimplemented");
  139. return false;
  140. }
  141. accelerate_draw = is_indexed ? AccelDraw::Indexed : AccelDraw::Arrays;
  142. DrawTriangles();
  143. return true;
  144. }
  145. void RasterizerOpenGL::DrawTriangles() {
  146. MICROPROFILE_SCOPE(OpenGL_Drawing);
  147. UNIMPLEMENTED();
  148. }
  149. void RasterizerOpenGL::NotifyMaxwellRegisterChanged(u32 id) {}
  150. void RasterizerOpenGL::FlushAll() {
  151. MICROPROFILE_SCOPE(OpenGL_CacheManagement);
  152. res_cache.FlushAll();
  153. }
  154. void RasterizerOpenGL::FlushRegion(VAddr addr, u64 size) {
  155. MICROPROFILE_SCOPE(OpenGL_CacheManagement);
  156. res_cache.FlushRegion(addr, size);
  157. }
  158. void RasterizerOpenGL::InvalidateRegion(VAddr addr, u64 size) {
  159. MICROPROFILE_SCOPE(OpenGL_CacheManagement);
  160. res_cache.InvalidateRegion(addr, size, nullptr);
  161. }
  162. void RasterizerOpenGL::FlushAndInvalidateRegion(VAddr addr, u64 size) {
  163. MICROPROFILE_SCOPE(OpenGL_CacheManagement);
  164. res_cache.FlushRegion(addr, size);
  165. res_cache.InvalidateRegion(addr, size, nullptr);
  166. }
  167. bool RasterizerOpenGL::AccelerateDisplayTransfer(const void* config) {
  168. MICROPROFILE_SCOPE(OpenGL_Blits);
  169. ASSERT_MSG(false, "Unimplemented");
  170. return true;
  171. }
  172. bool RasterizerOpenGL::AccelerateTextureCopy(const void* config) {
  173. ASSERT_MSG(false, "Unimplemented");
  174. return true;
  175. }
  176. bool RasterizerOpenGL::AccelerateFill(const void* config) {
  177. ASSERT_MSG(false, "Unimplemented");
  178. return true;
  179. }
  180. bool RasterizerOpenGL::AccelerateDisplay(const Tegra::FramebufferConfig& framebuffer,
  181. VAddr framebuffer_addr, u32 pixel_stride,
  182. ScreenInfo& screen_info) {
  183. if (framebuffer_addr == 0) {
  184. return false;
  185. }
  186. MICROPROFILE_SCOPE(OpenGL_CacheManagement);
  187. SurfaceParams src_params;
  188. src_params.addr = framebuffer_addr;
  189. src_params.width = std::min(framebuffer.width, pixel_stride);
  190. src_params.height = framebuffer.height;
  191. src_params.stride = pixel_stride;
  192. src_params.is_tiled = false;
  193. src_params.pixel_format =
  194. SurfaceParams::PixelFormatFromGPUPixelFormat(framebuffer.pixel_format);
  195. src_params.UpdateParams();
  196. MathUtil::Rectangle<u32> src_rect;
  197. Surface src_surface;
  198. std::tie(src_surface, src_rect) =
  199. res_cache.GetSurfaceSubRect(src_params, ScaleMatch::Ignore, true);
  200. if (src_surface == nullptr) {
  201. return false;
  202. }
  203. u32 scaled_width = src_surface->GetScaledWidth();
  204. u32 scaled_height = src_surface->GetScaledHeight();
  205. screen_info.display_texcoords = MathUtil::Rectangle<float>(
  206. (float)src_rect.bottom / (float)scaled_height, (float)src_rect.left / (float)scaled_width,
  207. (float)src_rect.top / (float)scaled_height, (float)src_rect.right / (float)scaled_width);
  208. screen_info.display_texture = src_surface->texture.handle;
  209. return true;
  210. }
  211. void RasterizerOpenGL::SetShader() {
  212. // TODO(bunnei): The below sets up a static test shader for passing untransformed vertices to
  213. // OpenGL for rendering. This should be removed/replaced when we start emulating Maxwell
  214. // shaders.
  215. static constexpr char vertex_shader[] = R"(
  216. #version 150 core
  217. in vec2 vert_position;
  218. in vec2 vert_tex_coord;
  219. out vec2 frag_tex_coord;
  220. void main() {
  221. // Multiply input position by the rotscale part of the matrix and then manually translate by
  222. // the last column. This is equivalent to using a full 3x3 matrix and expanding the vector
  223. // to `vec3(vert_position.xy, 1.0)`
  224. gl_Position = vec4(mat2(mat3x2(0.0015625f, 0.0, 0.0, -0.0027778, -1.0, 1.0)) * vert_position + mat3x2(0.0015625f, 0.0, 0.0, -0.0027778, -1.0, 1.0)[2], 0.0, 1.0);
  225. frag_tex_coord = vert_tex_coord;
  226. }
  227. )";
  228. static constexpr char fragment_shader[] = R"(
  229. #version 150 core
  230. in vec2 frag_tex_coord;
  231. out vec4 color;
  232. uniform sampler2D color_texture;
  233. void main() {
  234. color = vec4(1.0, 0.0, 1.0, 0.0);
  235. }
  236. )";
  237. if (current_shader) {
  238. return;
  239. }
  240. LOG_ERROR(HW_GPU, "Emulated shaders are not supported! Using a passthrough shader.");
  241. current_shader = &test_shader;
  242. if (has_ARB_separate_shader_objects) {
  243. test_shader.shader.Create(vertex_shader, nullptr, fragment_shader, {}, true);
  244. glActiveShaderProgram(pipeline.handle, test_shader.shader.handle);
  245. } else {
  246. ASSERT_MSG(false, "Unimplemented");
  247. }
  248. state.draw.shader_program = test_shader.shader.handle;
  249. state.Apply();
  250. if (has_ARB_separate_shader_objects) {
  251. state.draw.shader_program = 0;
  252. state.Apply();
  253. }
  254. }
  255. void RasterizerOpenGL::SyncClipEnabled() {
  256. ASSERT_MSG(false, "Unimplemented");
  257. }
  258. void RasterizerOpenGL::SyncClipCoef() {
  259. ASSERT_MSG(false, "Unimplemented");
  260. }
  261. void RasterizerOpenGL::SyncCullMode() {
  262. ASSERT_MSG(false, "Unimplemented");
  263. }
  264. void RasterizerOpenGL::SyncDepthScale() {
  265. ASSERT_MSG(false, "Unimplemented");
  266. }
  267. void RasterizerOpenGL::SyncDepthOffset() {
  268. ASSERT_MSG(false, "Unimplemented");
  269. }
  270. void RasterizerOpenGL::SyncBlendEnabled() {
  271. ASSERT_MSG(false, "Unimplemented");
  272. }
  273. void RasterizerOpenGL::SyncBlendFuncs() {
  274. ASSERT_MSG(false, "Unimplemented");
  275. }
  276. void RasterizerOpenGL::SyncBlendColor() {
  277. ASSERT_MSG(false, "Unimplemented");
  278. }