{"action":"created","issue":{"url":"https://api.github.com/repos/citra-emu/citra/issues/3645","repository_url":"https://api.github.com/repos/citra-emu/citra","labels_url":"https://api.github.com/repos/citra-emu/citra/issues/3645/labels{/name}","comments_url":"https://api.github.com/repos/citra-emu/citra/issues/3645/comments","events_url":"https://api.github.com/repos/citra-emu/citra/issues/3645/events","html_url":"https://github.com/citra-emu/citra/pull/3645","id":312952529,"number":3645,"title":"renderer_opengl: refactor shader & program objects and add shader manager for rasterizer","user":{"login":"wwylele","id":4592895,"avatar_url":"https://avatars0.githubusercontent.com/u/4592895?v=4","gravatar_id":"","url":"https://api.github.com/users/wwylele","html_url":"https://github.com/wwylele","followers_url":"https://api.github.com/users/wwylele/followers","following_url":"https://api.github.com/users/wwylele/following{/other_user}","gists_url":"https://api.github.com/users/wwylele/gists{/gist_id}","starred_url":"https://api.github.com/users/wwylele/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wwylele/subscriptions","organizations_url":"https://api.github.com/users/wwylele/orgs","repos_url":"https://api.github.com/users/wwylele/repos","events_url":"https://api.github.com/users/wwylele/events{/privacy}","received_events_url":"https://api.github.com/users/wwylele/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":2,"created_at":"2018-04-10T14:36:57Z","updated_at":"2018-04-15T19:07:50Z","closed_at":null,"author_association":"MEMBER","pull_request":{"url":"https://api.github.com/repos/citra-emu/citra/pulls/3645","html_url":"https://github.com/citra-emu/citra/pull/3645","diff_url":"https://github.com/citra-emu/citra/pull/3645.diff","patch_url":"https://github.com/citra-emu/citra/pull/3645.patch"},"body":"## Motivation\r\n\r\nWe currently have an ambiguous concept in our code: a \"shader\" (`OGLShader` class) represents a OpenGL program object, not a shader object. This works fine till now because we either use completely fixed program (hard-coded GLSL), or program where only the fragment shader is configurable. In this case there is a well-defined 1:1 mapping between shader source code and program objects. However with #3499 pending, we are going to decompile PICA vertex & geometry shaders to GLSL as well, which means the vertex shader and the geometry shader are also configurable, breaking the 1:1 mapping between program objects and shader source code.\r\n\r\nThis PR is extracted from the bulk change in #3499. It intends to redefine program resource and shader resource to match what they are in OpenGL, and to add a manager that can \"mix\" shader stages to form a new program.\r\n\r\n## Separate shader objects (SSO)\r\nTo mix shader stages, the extension [ARB_separate_shader_objects](https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_separate_shader_objects.txt) is used. Shader objects for each stage is linked to their own standalone program objects. These programs then attach to a pipeline object on drawing. \r\n\r\nSince it is an extension that is not guaranteed supported on all devices, a fallback path is also provided. In the fallback path, shader objects are not linked until being used. The linked programs are also cached to avoid relinking. \r\n\r\n## \"Shader stage object\"\r\nA new concept \"shader stage object\" is introduced, which represents either a shader object, used for the fallback path, or a program object produced by linking a single shader object, used for the SSO path. This conceptual object is now what shader cache caches (instead of full programs)\r\n\r\n## Shader generation & management model and interfaces\r\n\r\nIn this new code, gl_shader_manager manages most shader-related work, which were previously handled directly by the rasterizer. This manager exposes the following functions\r\n - `Use{Type}{Stage}Shader({ConfigurationType} config...)`\r\n   These functions use config parameters to generate a shader stage object (or try to match one in the cache) and set it ready to use. The `{Stage}` can be `Vertex`, `Geometry` or `Fragment`, representing the three stages in a OpenGL program. `{Type}` specify what major rendering method is being used. For example, for vertex shader, there will be two types: `Trivial` for the old CPU shader emulation path and the vertex shader simply passes on the vertices; `Programmable` for new GPU shader emulation where the vertex shader is decompiled from PICA shader. `{ConfigurationType}` is a package enough for generate a new shader source for this type.\r\n    Generally speaking, each `UseXXXShader` function invokes a corresponding cache manager object, which on cache miss calls a corresponding function in gl_shader_gen to get the source code to generate a new shader stage object.\r\n - `ApplyTo`\r\n   This applies all shader programs previously set by `UseXXXShader` functions to a OpenGLState object. The caller can then `Apply` this state and start drawing using the shaders.\r\n\r\n## Shader uniform interface\r\n\r\nWe only use two methods to communicate between shader program and main program: textures and interface blocks. Commonly, these two methods only needs a hard-coded binding point setting at the beginning, and don't require any more configuration to the shader/program objects afterwards. In fact, they can be directly set in shader source code with In-Shader Specification extension (ARB_shading_language_420pack). To avoid extension checking & fallback boilerplate, we still sets the binding manually, while conceptually considering it as a part of shader compilation/linkage process. Therefore the binding setting is integrated in the shader manager, right after a program object is generated. Here \"Program object is generated\" means either when a shader stage object is generated for the SSO path, or when the program is linked for the fallback path.\r\n\r\nThe binding setting is done by `SetShaderUniformBlockBindings` and `SetShaderSamplerBindings`. They each contains a list of uniform blocks / texture samples possibly used by all shader stages. Currently only one uniform block is there, but more will be added for GPU shader emulation.\r\n\r\n## What is going to be added by glvtx after this PR\r\n - more shader source generation function to gl_shader_gen (possibly in multiple files if they are too long)\r\n - correspondingly more `UseXXXShader` functions in the manager, and more internal shader cache for each shader type.\r\n - gl_rasterizer calls more `UseXXXShader` functions to draw with GPU shader emulation.\n\n<!-- Reviewable:start -->\n---\nThis change is [<img src=\"https://reviewable.io/review_button.svg\" height=\"34\" align=\"absmiddle\" alt=\"Reviewable\"/>](https://reviewable.io/reviews/citra-emu/citra/3645)\n<!-- Reviewable:end -->\n"},"comment":{"url":"https://api.github.com/repos/citra-emu/citra/issues/comments/381430221","html_url":"https://github.com/citra-emu/citra/pull/3645#issuecomment-381430221","issue_url":"https://api.github.com/repos/citra-emu/citra/issues/3645","id":381430221,"user":{"login":"wwylele","id":4592895,"avatar_url":"https://avatars0.githubusercontent.com/u/4592895?v=4","gravatar_id":"","url":"https://api.github.com/users/wwylele","html_url":"https://github.com/wwylele","followers_url":"https://api.github.com/users/wwylele/followers","following_url":"https://api.github.com/users/wwylele/following{/other_user}","gists_url":"https://api.github.com/users/wwylele/gists{/gist_id}","starred_url":"https://api.github.com/users/wwylele/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wwylele/subscriptions","organizations_url":"https://api.github.com/users/wwylele/orgs","repos_url":"https://api.github.com/users/wwylele/repos","events_url":"https://api.github.com/users/wwylele/events{/privacy}","received_events_url":"https://api.github.com/users/wwylele/received_events","type":"User","site_admin":false},"created_at":"2018-04-15T19:07:50Z","updated_at":"2018-04-15T19:07:50Z","author_association":"MEMBER","body":"I'll merge this tomorrow if no more comments.\r\n\r\nAs it has been ported to yuzu and merged there I assume it is already reviewed on their side = no main design problem. Small nits can be fixed in follow-up PRs."}}
{"actor":{"display_login":"wwylele"}}