VideoCommon/RenderBase: Use a std::string_view with CreateShaderFromSource()

Greatly simplifies the overall interface when it comes to compiling
shaders. Also allows getting rid of a std::string overload of the same
name. Now std::string and const char* both go through the same function.
This commit is contained in:
Lioncash
2019-05-30 03:07:40 -04:00
parent 80d8173d29
commit e60268bd42
25 changed files with 94 additions and 117 deletions

View File

@ -95,9 +95,9 @@ std::unique_ptr<AbstractStagingTexture> Renderer::CreateStagingTexture(StagingTe
}
std::unique_ptr<AbstractShader> Renderer::CreateShaderFromSource(ShaderStage stage,
const char* source, size_t length)
std::string_view source)
{
return VKShader::CreateFromSource(stage, source, length);
return VKShader::CreateFromSource(stage, source);
}
std::unique_ptr<AbstractShader> Renderer::CreateShaderFromBinary(ShaderStage stage,

View File

@ -42,8 +42,8 @@ public:
std::unique_ptr<AbstractFramebuffer>
CreateFramebuffer(AbstractTexture* color_attachment, AbstractTexture* depth_attachment) override;
std::unique_ptr<AbstractShader> CreateShaderFromSource(ShaderStage stage, const char* source,
size_t length) override;
std::unique_ptr<AbstractShader> CreateShaderFromSource(ShaderStage stage,
std::string_view source) override;
std::unique_ptr<AbstractShader> CreateShaderFromBinary(ShaderStage stage, const void* data,
size_t length) override;
std::unique_ptr<NativeVertexFormat>

View File

@ -35,11 +35,6 @@ bool InitializeGlslang();
// Resource limits used when compiling shaders
static const TBuiltInResource* GetCompilerResourceLimits();
// Compile a shader to SPIR-V via glslang
static bool CompileShaderToSPV(SPIRVCodeVector* out_code, EShLanguage stage,
const char* stage_filename, const char* source_code,
size_t source_code_length, const char* header, size_t header_length);
// Regarding the UBO bind points, we subtract one from the binding index because
// the OpenGL backend requires UBO #0 for non-block uniforms (at least on NV).
// This allows us to share the same shaders but use bind point #0 in the Vulkan
@ -114,8 +109,7 @@ static const char SUBGROUP_HELPER_HEADER[] = R"(
)";
bool CompileShaderToSPV(SPIRVCodeVector* out_code, EShLanguage stage, const char* stage_filename,
const char* source_code, size_t source_code_length, const char* header,
size_t header_length)
std::string_view source, std::string_view header)
{
if (!InitializeGlslang())
return false;
@ -129,16 +123,16 @@ bool CompileShaderToSPV(SPIRVCodeVector* out_code, EShLanguage stage, const char
int default_version = 450;
std::string full_source_code;
const char* pass_source_code = source_code;
int pass_source_code_length = static_cast<int>(source_code_length);
if (header_length > 0)
const char* pass_source_code = source.data();
int pass_source_code_length = static_cast<int>(source.size());
if (!header.empty())
{
constexpr size_t subgroup_helper_header_length = ArraySize(SUBGROUP_HELPER_HEADER) - 1;
full_source_code.reserve(header_length + subgroup_helper_header_length + source_code_length);
full_source_code.append(header, header_length);
full_source_code.reserve(header.size() + subgroup_helper_header_length + source.size());
full_source_code.append(header);
if (g_vulkan_context->SupportsShaderSubgroupOperations())
full_source_code.append(SUBGROUP_HELPER_HEADER, subgroup_helper_header_length);
full_source_code.append(source_code, source_code_length);
full_source_code.append(source);
pass_source_code = full_source_code.c_str();
pass_source_code_length = static_cast<int>(full_source_code.length());
}
@ -362,32 +356,24 @@ const TBuiltInResource* GetCompilerResourceLimits()
return &limits;
}
bool CompileVertexShader(SPIRVCodeVector* out_code, const char* source_code,
size_t source_code_length)
bool CompileVertexShader(SPIRVCodeVector* out_code, std::string_view source_code)
{
return CompileShaderToSPV(out_code, EShLangVertex, "vs", source_code, source_code_length,
SHADER_HEADER, sizeof(SHADER_HEADER) - 1);
return CompileShaderToSPV(out_code, EShLangVertex, "vs", source_code, SHADER_HEADER);
}
bool CompileGeometryShader(SPIRVCodeVector* out_code, const char* source_code,
size_t source_code_length)
bool CompileGeometryShader(SPIRVCodeVector* out_code, std::string_view source_code)
{
return CompileShaderToSPV(out_code, EShLangGeometry, "gs", source_code, source_code_length,
SHADER_HEADER, sizeof(SHADER_HEADER) - 1);
return CompileShaderToSPV(out_code, EShLangGeometry, "gs", source_code, SHADER_HEADER);
}
bool CompileFragmentShader(SPIRVCodeVector* out_code, const char* source_code,
size_t source_code_length)
bool CompileFragmentShader(SPIRVCodeVector* out_code, std::string_view source_code)
{
return CompileShaderToSPV(out_code, EShLangFragment, "ps", source_code, source_code_length,
SHADER_HEADER, sizeof(SHADER_HEADER) - 1);
return CompileShaderToSPV(out_code, EShLangFragment, "ps", source_code, SHADER_HEADER);
}
bool CompileComputeShader(SPIRVCodeVector* out_code, const char* source_code,
size_t source_code_length)
bool CompileComputeShader(SPIRVCodeVector* out_code, std::string_view source_code)
{
return CompileShaderToSPV(out_code, EShLangCompute, "cs", source_code, source_code_length,
COMPUTE_SHADER_HEADER, sizeof(COMPUTE_SHADER_HEADER) - 1);
return CompileShaderToSPV(out_code, EShLangCompute, "cs", source_code, COMPUTE_SHADER_HEADER);
}
} // namespace ShaderCompiler

View File

@ -5,6 +5,7 @@
#pragma once
#include <cstddef>
#include <string_view>
#include <vector>
#include "Common/CommonTypes.h"
@ -18,20 +19,16 @@ using SPIRVCodeType = u32;
using SPIRVCodeVector = std::vector<SPIRVCodeType>;
// Compile a vertex shader to SPIR-V.
bool CompileVertexShader(SPIRVCodeVector* out_code, const char* source_code,
size_t source_code_length);
bool CompileVertexShader(SPIRVCodeVector* out_code, std::string_view source_code);
// Compile a geometry shader to SPIR-V.
bool CompileGeometryShader(SPIRVCodeVector* out_code, const char* source_code,
size_t source_code_length);
bool CompileGeometryShader(SPIRVCodeVector* out_code, std::string_view source_code);
// Compile a fragment shader to SPIR-V.
bool CompileFragmentShader(SPIRVCodeVector* out_code, const char* source_code,
size_t source_code_length);
bool CompileFragmentShader(SPIRVCodeVector* out_code, std::string_view source_code);
// Compile a compute shader to SPIR-V.
bool CompileComputeShader(SPIRVCodeVector* out_code, const char* source_code,
size_t source_code_length);
bool CompileComputeShader(SPIRVCodeVector* out_code, std::string_view source_code);
} // namespace ShaderCompiler
} // namespace Vulkan

View File

@ -86,24 +86,23 @@ static std::unique_ptr<VKShader> CreateShaderObject(ShaderStage stage,
return std::make_unique<VKShader>(std::move(spv), pipeline);
}
std::unique_ptr<VKShader> VKShader::CreateFromSource(ShaderStage stage, const char* source,
size_t length)
std::unique_ptr<VKShader> VKShader::CreateFromSource(ShaderStage stage, std::string_view source)
{
ShaderCompiler::SPIRVCodeVector spv;
bool result;
switch (stage)
{
case ShaderStage::Vertex:
result = ShaderCompiler::CompileVertexShader(&spv, source, length);
result = ShaderCompiler::CompileVertexShader(&spv, source);
break;
case ShaderStage::Geometry:
result = ShaderCompiler::CompileGeometryShader(&spv, source, length);
result = ShaderCompiler::CompileGeometryShader(&spv, source);
break;
case ShaderStage::Pixel:
result = ShaderCompiler::CompileFragmentShader(&spv, source, length);
result = ShaderCompiler::CompileFragmentShader(&spv, source);
break;
case ShaderStage::Compute:
result = ShaderCompiler::CompileComputeShader(&spv, source, length);
result = ShaderCompiler::CompileComputeShader(&spv, source);
break;
default:
result = false;

View File

@ -6,6 +6,7 @@
#include <cstddef>
#include <memory>
#include <string_view>
#include <vector>
#include "Common/CommonTypes.h"
@ -25,8 +26,7 @@ public:
VkPipeline GetComputePipeline() const { return m_compute_pipeline; }
BinaryData GetBinary() const override;
static std::unique_ptr<VKShader> CreateFromSource(ShaderStage stage, const char* source,
size_t length);
static std::unique_ptr<VKShader> CreateFromSource(ShaderStage stage, std::string_view source);
static std::unique_ptr<VKShader> CreateFromBinary(ShaderStage stage, const void* data,
size_t length);