Refactor ShaderModule creation to use a Builder pattern

BUG=dawn:270

Change-Id: Iedae1a5500b1eb65abb84ff59f68d829c5c22c2b
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/13500
Commit-Queue: Ryan Harrison <rharrison@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
Ryan Harrison 2019-11-14 16:10:45 +00:00 committed by Commit Bot service account
parent 321c12255e
commit 58dbfcae38
11 changed files with 78 additions and 16 deletions

View File

@ -274,7 +274,7 @@ namespace dawn_native { namespace d3d12 {
} }
ResultOrError<ShaderModuleBase*> Device::CreateShaderModuleImpl( ResultOrError<ShaderModuleBase*> Device::CreateShaderModuleImpl(
const ShaderModuleDescriptor* descriptor) { const ShaderModuleDescriptor* descriptor) {
return new ShaderModule(this, descriptor); return ShaderModule::Create(this, descriptor);
} }
ResultOrError<SwapChainBase*> Device::CreateSwapChainImpl( ResultOrError<SwapChainBase*> Device::CreateSwapChainImpl(
const SwapChainDescriptor* descriptor) { const SwapChainDescriptor* descriptor) {

View File

@ -24,11 +24,25 @@
namespace dawn_native { namespace d3d12 { namespace dawn_native { namespace d3d12 {
// static
ResultOrError<ShaderModule*> ShaderModule::Create(Device* device,
const ShaderModuleDescriptor* descriptor) {
std::unique_ptr<ShaderModule> module(new ShaderModule(device, descriptor));
if (!module)
return DAWN_VALIDATION_ERROR("Unable to create ShaderModule");
DAWN_TRY(module->Initialize(descriptor));
return module.release();
}
ShaderModule::ShaderModule(Device* device, const ShaderModuleDescriptor* descriptor) ShaderModule::ShaderModule(Device* device, const ShaderModuleDescriptor* descriptor)
: ShaderModuleBase(device, descriptor) { : ShaderModuleBase(device, descriptor) {
}
MaybeError ShaderModule::Initialize(const ShaderModuleDescriptor* descriptor) {
mSpirv.assign(descriptor->code, descriptor->code + descriptor->codeSize); mSpirv.assign(descriptor->code, descriptor->code + descriptor->codeSize);
spirv_cross::CompilerHLSL compiler(mSpirv); spirv_cross::CompilerHLSL compiler(mSpirv);
ExtractSpirvInfo(compiler); ExtractSpirvInfo(compiler);
return {};
} }
const std::string ShaderModule::GetHLSLSource(PipelineLayout* layout) const { const std::string ShaderModule::GetHLSLSource(PipelineLayout* layout) const {

View File

@ -24,11 +24,15 @@ namespace dawn_native { namespace d3d12 {
class ShaderModule : public ShaderModuleBase { class ShaderModule : public ShaderModuleBase {
public: public:
ShaderModule(Device* device, const ShaderModuleDescriptor* descriptor); static ResultOrError<ShaderModule*> Create(Device* device,
const ShaderModuleDescriptor* descriptor);
const std::string GetHLSLSource(PipelineLayout* layout) const; const std::string GetHLSLSource(PipelineLayout* layout) const;
private: private:
ShaderModule(Device* device, const ShaderModuleDescriptor* descriptor);
MaybeError Initialize(const ShaderModuleDescriptor* descriptor);
std::vector<uint32_t> mSpirv; std::vector<uint32_t> mSpirv;
}; };

View File

@ -129,7 +129,7 @@ namespace dawn_native { namespace metal {
} }
ResultOrError<ShaderModuleBase*> Device::CreateShaderModuleImpl( ResultOrError<ShaderModuleBase*> Device::CreateShaderModuleImpl(
const ShaderModuleDescriptor* descriptor) { const ShaderModuleDescriptor* descriptor) {
return new ShaderModule(this, descriptor); return ShaderModule::Create(this, descriptor);
} }
ResultOrError<SwapChainBase*> Device::CreateSwapChainImpl( ResultOrError<SwapChainBase*> Device::CreateSwapChainImpl(
const SwapChainDescriptor* descriptor) { const SwapChainDescriptor* descriptor) {

View File

@ -19,6 +19,8 @@
#import <Metal/Metal.h> #import <Metal/Metal.h>
#include "dawn_native/Error.h"
namespace spirv_cross { namespace spirv_cross {
class CompilerMSL; class CompilerMSL;
} }
@ -30,7 +32,8 @@ namespace dawn_native { namespace metal {
class ShaderModule : public ShaderModuleBase { class ShaderModule : public ShaderModuleBase {
public: public:
ShaderModule(Device* device, const ShaderModuleDescriptor* descriptor); static ResultOrError<ShaderModule*> Create(Device* device,
const ShaderModuleDescriptor* descriptor);
struct MetalFunctionData { struct MetalFunctionData {
id<MTLFunction> function; id<MTLFunction> function;
@ -45,6 +48,9 @@ namespace dawn_native { namespace metal {
const PipelineLayout* layout) const; const PipelineLayout* layout) const;
private: private:
ShaderModule(Device* device, const ShaderModuleDescriptor* descriptor);
MaybeError Initialize(const ShaderModuleDescriptor* descriptor);
// Calling compile on CompilerMSL somehow changes internal state that makes subsequent // Calling compile on CompilerMSL somehow changes internal state that makes subsequent
// compiles return invalid MSL. We keep the spirv around and recreate the compiler everytime // compiles return invalid MSL. We keep the spirv around and recreate the compiler everytime
// we need to use it. // we need to use it.

View File

@ -38,13 +38,27 @@ namespace dawn_native { namespace metal {
UNREACHABLE(); UNREACHABLE();
} }
} }
} // namespace
// static
ResultOrError<ShaderModule*> ShaderModule::Create(Device* device,
const ShaderModuleDescriptor* descriptor) {
std::unique_ptr<ShaderModule> module(new ShaderModule(device, descriptor));
if (!module)
return DAWN_VALIDATION_ERROR("Unable to create ShaderModule");
DAWN_TRY(module->Initialize(descriptor));
return module.release();
} }
ShaderModule::ShaderModule(Device* device, const ShaderModuleDescriptor* descriptor) ShaderModule::ShaderModule(Device* device, const ShaderModuleDescriptor* descriptor)
: ShaderModuleBase(device, descriptor) { : ShaderModuleBase(device, descriptor) {
}
MaybeError ShaderModule::Initialize(const ShaderModuleDescriptor* descriptor) {
mSpirv.assign(descriptor->code, descriptor->code + descriptor->codeSize); mSpirv.assign(descriptor->code, descriptor->code + descriptor->codeSize);
spirv_cross::CompilerMSL compiler(mSpirv); spirv_cross::CompilerMSL compiler(mSpirv);
ExtractSpirvInfo(compiler); ExtractSpirvInfo(compiler);
return {};
} }
ShaderModule::MetalFunctionData ShaderModule::GetFunction(const char* functionName, ShaderModule::MetalFunctionData ShaderModule::GetFunction(const char* functionName,

View File

@ -99,7 +99,7 @@ namespace dawn_native { namespace opengl {
} }
ResultOrError<ShaderModuleBase*> Device::CreateShaderModuleImpl( ResultOrError<ShaderModuleBase*> Device::CreateShaderModuleImpl(
const ShaderModuleDescriptor* descriptor) { const ShaderModuleDescriptor* descriptor) {
return new ShaderModule(this, descriptor); return ShaderModule::Create(this, descriptor);
} }
ResultOrError<SwapChainBase*> Device::CreateSwapChainImpl( ResultOrError<SwapChainBase*> Device::CreateSwapChainImpl(
const SwapChainDescriptor* descriptor) { const SwapChainDescriptor* descriptor) {

View File

@ -47,8 +47,29 @@ namespace dawn_native { namespace opengl {
return o.str(); return o.str();
} }
// static
ResultOrError<ShaderModule*> ShaderModule::Create(Device* device,
const ShaderModuleDescriptor* descriptor) {
std::unique_ptr<ShaderModule> module(new ShaderModule(device, descriptor));
if (!module)
return DAWN_VALIDATION_ERROR("Unable to create ShaderModule");
DAWN_TRY(module->Initialize(descriptor));
return module.release();
}
const char* ShaderModule::GetSource() const {
return mGlslSource.c_str();
}
const ShaderModule::CombinedSamplerInfo& ShaderModule::GetCombinedSamplerInfo() const {
return mCombinedInfo;
}
ShaderModule::ShaderModule(Device* device, const ShaderModuleDescriptor* descriptor) ShaderModule::ShaderModule(Device* device, const ShaderModuleDescriptor* descriptor)
: ShaderModuleBase(device, descriptor) { : ShaderModuleBase(device, descriptor) {
}
MaybeError ShaderModule::Initialize(const ShaderModuleDescriptor* descriptor) {
spirv_cross::CompilerGLSL compiler(descriptor->code, descriptor->codeSize); spirv_cross::CompilerGLSL compiler(descriptor->code, descriptor->codeSize);
// If these options are changed, the values in DawnSPIRVCrossGLSLFastFuzzer.cpp need to be // If these options are changed, the values in DawnSPIRVCrossGLSLFastFuzzer.cpp need to be
// updated. // updated.
@ -108,14 +129,7 @@ namespace dawn_native { namespace opengl {
} }
mGlslSource = compiler.compile(); mGlslSource = compiler.compile();
} return {};
const char* ShaderModule::GetSource() const {
return mGlslSource.c_str();
}
const ShaderModule::CombinedSamplerInfo& ShaderModule::GetCombinedSamplerInfo() const {
return mCombinedInfo;
} }
}} // namespace dawn_native::opengl }} // namespace dawn_native::opengl

View File

@ -40,7 +40,8 @@ namespace dawn_native { namespace opengl {
class ShaderModule : public ShaderModuleBase { class ShaderModule : public ShaderModuleBase {
public: public:
ShaderModule(Device* device, const ShaderModuleDescriptor* descriptor); static ResultOrError<ShaderModule*> Create(Device* device,
const ShaderModuleDescriptor* descriptor);
using CombinedSamplerInfo = std::vector<CombinedSampler>; using CombinedSamplerInfo = std::vector<CombinedSampler>;
@ -48,6 +49,9 @@ namespace dawn_native { namespace opengl {
const CombinedSamplerInfo& GetCombinedSamplerInfo() const; const CombinedSamplerInfo& GetCombinedSamplerInfo() const;
private: private:
ShaderModule(Device* device, const ShaderModuleDescriptor* descriptor);
MaybeError Initialize(const ShaderModuleDescriptor* descriptor);
CombinedSamplerInfo mCombinedInfo; CombinedSamplerInfo mCombinedInfo;
std::string mGlslSource; std::string mGlslSource;
}; };

View File

@ -25,11 +25,17 @@ namespace dawn_native { namespace vulkan {
// static // static
ResultOrError<ShaderModule*> ShaderModule::Create(Device* device, ResultOrError<ShaderModule*> ShaderModule::Create(Device* device,
const ShaderModuleDescriptor* descriptor) { const ShaderModuleDescriptor* descriptor) {
std::unique_ptr<ShaderModule> module = std::make_unique<ShaderModule>(device, descriptor); std::unique_ptr<ShaderModule> module(new ShaderModule(device, descriptor));
if (!module)
return DAWN_VALIDATION_ERROR("Unable to create ShaderModule");
DAWN_TRY(module->Initialize(descriptor)); DAWN_TRY(module->Initialize(descriptor));
return module.release(); return module.release();
} }
ShaderModule::ShaderModule(Device* device, const ShaderModuleDescriptor* descriptor)
: ShaderModuleBase(device, descriptor) {
}
MaybeError ShaderModule::Initialize(const ShaderModuleDescriptor* descriptor) { MaybeError ShaderModule::Initialize(const ShaderModuleDescriptor* descriptor) {
// Use SPIRV-Cross to extract info from the SPIRV even if Vulkan consumes SPIRV. We want to // Use SPIRV-Cross to extract info from the SPIRV even if Vulkan consumes SPIRV. We want to
// have a translation step eventually anyway. // have a translation step eventually anyway.

View File

@ -33,7 +33,7 @@ namespace dawn_native { namespace vulkan {
VkShaderModule GetHandle() const; VkShaderModule GetHandle() const;
private: private:
using ShaderModuleBase::ShaderModuleBase; ShaderModule(Device* device, const ShaderModuleDescriptor* descriptor);
MaybeError Initialize(const ShaderModuleDescriptor* descriptor); MaybeError Initialize(const ShaderModuleDescriptor* descriptor);
VkShaderModule mHandle = VK_NULL_HANDLE; VkShaderModule mHandle = VK_NULL_HANDLE;