Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeroen Bakker <jeroen@blender.org>2021-07-02 14:43:01 +0300
committerJeroen Bakker <jeroen@blender.org>2021-07-02 14:43:01 +0300
commitd8d007136719c67e02092b2511bb88f869616f84 (patch)
tree3437ca04ea8ed0574654e3c21898b3eaa38a2753
parent2436d361581d0c91221f4cf5ee6a75bc088824ae (diff)
GPU: Added push constants to shader interface
-rw-r--r--source/blender/gpu/opengl/gl_shader.cc13
-rw-r--r--source/blender/gpu/opengl/gl_shader.hh3
-rw-r--r--source/blender/gpu/opengl/gl_shader_interface.cc9
-rw-r--r--source/blender/gpu/opengl/gl_shader_interface.hh12
-rw-r--r--source/blender/gpu/opengl/gl_shader_patcher.cc26
-rw-r--r--source/blender/gpu/opengl/gl_shader_patcher.hh28
6 files changed, 55 insertions, 36 deletions
diff --git a/source/blender/gpu/opengl/gl_shader.cc b/source/blender/gpu/opengl/gl_shader.cc
index 9ad9ffebd00..b89f59f9557 100644
--- a/source/blender/gpu/opengl/gl_shader.cc
+++ b/source/blender/gpu/opengl/gl_shader.cc
@@ -148,8 +148,8 @@ GLuint GLShader::create_shader_stage(GLenum gl_stage, MutableSpan<const char *>
/* Patch the shader code using the first source slot. */
sources[0] = glsl_patch_get(gl_stage);
- converter_.patch(sources);
- if (converter_.has_errors()) {
+ patch_vulkan_to_opengl(patcher_context_, sources);
+ if (patcher_context_.has_errors()) {
compilation_failed_ = true;
return 0;
}
@@ -231,11 +231,12 @@ bool GLShader::finalize()
return false;
}
- interface = new GLShaderInterface(shader_program_);
+ interface = new GLShaderInterface(patcher_context_, shader_program_);
- /* Only patched sources are only freed when shader compilation and linking succeeds for
- * debugging. */
- converter_.free();
+ /* Patched sources are only freed when shader compilation and linking successful completed. In
+ * other cases they are kept for debugging purposes and will be GC'd when the GPUShader is freed.
+ */
+ patcher_context_.free_patched_sources();
return true;
}
diff --git a/source/blender/gpu/opengl/gl_shader.hh b/source/blender/gpu/opengl/gl_shader.hh
index 63dcbcbabae..dfc44119e50 100644
--- a/source/blender/gpu/opengl/gl_shader.hh
+++ b/source/blender/gpu/opengl/gl_shader.hh
@@ -50,7 +50,8 @@ class GLShader : public Shader {
bool compilation_failed_ = false;
eGPUShaderTFBType transform_feedback_type_ = GPU_SHADER_TFB_NONE;
- GLShaderPatcher converter_;
+
+ GLShaderPatcherContext patcher_context_;
public:
GLShader(const char *name);
diff --git a/source/blender/gpu/opengl/gl_shader_interface.cc b/source/blender/gpu/opengl/gl_shader_interface.cc
index 9cf072b2e8a..b2842020b25 100644
--- a/source/blender/gpu/opengl/gl_shader_interface.cc
+++ b/source/blender/gpu/opengl/gl_shader_interface.cc
@@ -145,7 +145,7 @@ static inline int ssbo_binding(int32_t program, uint32_t ssbo_index)
/** \name Creation / Destruction
* \{ */
-GLShaderInterface::GLShaderInterface(GLuint program)
+GLShaderInterface::GLShaderInterface(GLShaderPatcherContext &context, GLuint program)
{
/* Necessary to make #glUniform works. */
glUseProgram(program);
@@ -321,6 +321,13 @@ GLShaderInterface::GLShaderInterface(GLuint program)
// this->debug_print();
this->sort_inputs();
+
+ /* Push Constant Blocks */
+ /* Push constants are converted by GLShaderPatcher to regular uniform buffers. Here we retrieve
+ * the reference to its binding. */
+ if (context.push_constants.name) {
+ push_constant_input_ = ubo_get(context.push_constants.name->c_str());
+ }
}
GLShaderInterface::~GLShaderInterface()
diff --git a/source/blender/gpu/opengl/gl_shader_interface.hh b/source/blender/gpu/opengl/gl_shader_interface.hh
index 89a5b631047..059fedd83c6 100644
--- a/source/blender/gpu/opengl/gl_shader_interface.hh
+++ b/source/blender/gpu/opengl/gl_shader_interface.hh
@@ -34,6 +34,8 @@
#include "glew-mx.h"
+#include "gl_shader_patcher.hh"
+
#include "gpu_shader_interface.hh"
namespace blender::gpu {
@@ -48,13 +50,21 @@ class GLShaderInterface : public ShaderInterface {
/** Reference to VaoCaches using this interface */
Vector<GLVaoCache *> refs_;
+ /* Reference to the ubo binding that is used for push constants. */
+ const ShaderInput *push_constant_input_ = nullptr;
+
public:
- GLShaderInterface(GLuint program);
+ GLShaderInterface(GLShaderPatcherContext &context, GLuint program);
~GLShaderInterface();
void ref_add(GLVaoCache *ref);
void ref_remove(GLVaoCache *ref);
+ inline const ShaderInput *push_constant_get()
+ {
+ return push_constant_input_;
+ }
+
MEM_CXX_CLASS_ALLOC_FUNCS("GLShaderInterface");
};
diff --git a/source/blender/gpu/opengl/gl_shader_patcher.cc b/source/blender/gpu/opengl/gl_shader_patcher.cc
index 5d6a766fc6b..15ab4222ae9 100644
--- a/source/blender/gpu/opengl/gl_shader_patcher.cc
+++ b/source/blender/gpu/opengl/gl_shader_patcher.cc
@@ -68,7 +68,7 @@ class GLSLPatch {
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01232456789_";
public:
- virtual GLSLPatchResult patch(GLShaderPatchState &context, StringRef source) = 0;
+ virtual GLSLPatchResult patch(GLShaderPatcherContext &context, StringRef source) = 0;
protected:
static StringRef skip_whitespace(StringRef ref)
@@ -94,7 +94,7 @@ class PatchPushConstants : public GLSLPatch {
static constexpr StringRef LAYOUT_STD140 = "layout(std140)";
public:
- GLSLPatchResult patch(GLShaderPatchState &context, StringRef source) override
+ GLSLPatchResult patch(GLShaderPatcherContext &context, StringRef source) override
{
GLSLPatchResult result;
@@ -115,14 +115,14 @@ class PatchPushConstants : public GLSLPatch {
name = skip_whitespace(name);
name = extract_name(name);
- if (context.push_constants.name.empty()) {
+ if (!context.push_constants.name) {
context.push_constants.name = name;
}
else if (context.push_constants.name != name) {
CLOG_ERROR(&LOG,
"Detected different push_constants binding names ('%s' and '%s'). push_constants "
"binding names must be identical across all stages.",
- context.push_constants.name.c_str(),
+ context.push_constants.name->c_str(),
std::string(name).c_str());
result.state = GLShaderPatcherState::MismatchedPushConstantNames;
return result;
@@ -138,7 +138,7 @@ class PatchPushConstants : public GLSLPatch {
class GLSLPatcher : public GLSLPatch {
private:
- static void patch(GLShaderPatchState &context,
+ static void patch(GLShaderPatcherContext &context,
GLSLPatch &patch,
StringRef source,
GLSLPatchResult &r_result)
@@ -153,7 +153,7 @@ class GLSLPatcher : public GLSLPatch {
}
public:
- GLSLPatchResult patch(GLShaderPatchState &context, StringRef source) override
+ GLSLPatchResult patch(GLShaderPatcherContext &context, StringRef source) override
{
GLSLPatchResult result;
PatchPushConstants push_constants;
@@ -162,7 +162,7 @@ class GLSLPatcher : public GLSLPatch {
}
};
-void GLShaderPatcher::patch(MutableSpan<const char *> sources)
+void patch_vulkan_to_opengl(GLShaderPatcherContext &context, MutableSpan<const char *> sources)
{
for (int i = 0; i < sources.size(); i++) {
GLSLPatcher patcher;
@@ -174,8 +174,8 @@ void GLShaderPatcher::patch(MutableSpan<const char *> sources)
case GLShaderPatcherState::OkChanged:
BLI_assert(patch_result.patched_glsl);
- patched_sources_.append(*patch_result.patched_glsl);
- sources[i] = patched_sources_.last().c_str();
+ context.patched_sources.append(*patch_result.patched_glsl);
+ sources[i] = context.patched_sources.last().c_str();
/* Keep any errors from previous stages. */
if (context.state == GLShaderPatcherState::OkUnchanged) {
@@ -191,14 +191,14 @@ void GLShaderPatcher::patch(MutableSpan<const char *> sources)
}
}
-bool GLShaderPatcher::has_errors() const
+void GLShaderPatcherContext::free_patched_sources()
{
- return is_error_state(context.state);
+ patched_sources.clear();
}
-void GLShaderPatcher::free()
+bool GLShaderPatcherContext::has_errors() const
{
- patched_sources_.clear();
+ return is_error_state(state);
}
} // namespace blender::gpu
diff --git a/source/blender/gpu/opengl/gl_shader_patcher.hh b/source/blender/gpu/opengl/gl_shader_patcher.hh
index 854de2b9ab2..7578600df53 100644
--- a/source/blender/gpu/opengl/gl_shader_patcher.hh
+++ b/source/blender/gpu/opengl/gl_shader_patcher.hh
@@ -26,6 +26,8 @@
#include "BLI_string_ref.hh"
#include "BLI_vector.hh"
+#include <optional>
+
namespace blender::gpu {
enum class GLShaderPatcherState {
@@ -34,26 +36,24 @@ enum class GLShaderPatcherState {
MismatchedPushConstantNames,
};
-struct GLShaderPatchState {
+/** State to keep over GLSL compilation stages, linkage and shader_interface building. */
+struct GLShaderPatcherContext {
GLShaderPatcherState state = GLShaderPatcherState::OkUnchanged;
+
+ /**
+ * All patched sources. During compilation stage source code is references as `const
+ * char*` These needs to be owned by a `std::string`.
+ */
+ Vector<std::string> patched_sources;
struct {
- std::string name;
+ std::optional<std::string> name;
} push_constants;
-};
-class GLShaderPatcher {
- public:
- GLShaderPatchState context;
-
- private:
- Vector<std::string> patched_sources_;
-
- public:
- void patch(MutableSpan<const char *> sources);
bool has_errors() const;
- void free();
- MEM_CXX_CLASS_ALLOC_FUNCS("GLShaderPatcher");
+ void free_patched_sources();
};
+void patch_vulkan_to_opengl(GLShaderPatcherContext &context, MutableSpan<const char *> sources);
+
} // namespace blender::gpu