Skip to content

Commit

Permalink
matdbg: add support for essl1 shader debugging
Browse files Browse the repository at this point in the history
Fixes #8261
  • Loading branch information
elizagamedev committed Jan 31, 2025
1 parent 87bdf96 commit 125fe7c
Show file tree
Hide file tree
Showing 22 changed files with 170 additions and 108 deletions.
2 changes: 2 additions & 0 deletions NEW_RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ for next branch cut* header.
appropriate header in [RELEASE_NOTES.md](./RELEASE_NOTES.md).

## Release notes for next branch cut

- matdbg: Add support for debugging ESSL 1.0 shaders
10 changes: 10 additions & 0 deletions filament/backend/include/private/backend/Driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,16 @@ class Driver {

virtual ShaderModel getShaderModel() const noexcept = 0;

// The shader language used for shaders for this driver, used to inform matdbg.
//
// For OpenGL, this distinguishes whether the driver's shaders are powered by ESSL1 or ESSL3.
// This information is used by matdbg to display the correct shader code to the web UI and patch
// the correct chunk when rebuilding shaders live.
//
// Metal shaders can either be MSL or Metal libraries, but at time of writing, matdbg can only
// interface with MSL.
virtual ShaderLanguage getShaderLanguage() const noexcept = 0;

// Returns the dispatcher. This is only called once during initialization of the CommandStream,
// so it doesn't matter that it's virtual.
virtual Dispatcher getDispatcher() const noexcept = 0;
Expand Down
1 change: 1 addition & 0 deletions filament/backend/src/metal/MetalDriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ class MetalDriver final : public DriverBase {
MetalContext* mContext;

ShaderModel getShaderModel() const noexcept final;
ShaderLanguage getShaderLanguage() const noexcept final;

// Overrides the default implementation by wrapping the call to fn in an @autoreleasepool block.
void execute(std::function<void(void)> const& fn) noexcept final;
Expand Down
4 changes: 4 additions & 0 deletions filament/backend/src/metal/MetalDriver.mm
Original file line number Diff line number Diff line change
Expand Up @@ -946,6 +946,10 @@
#endif
}

ShaderLanguage MetalDriver::getShaderLanguage() const noexcept {
return ShaderLanguage::MSL;
}

Handle<HwStream> MetalDriver::createStreamNative(void* stream) {
return {};
}
Expand Down
4 changes: 4 additions & 0 deletions filament/backend/src/noop/NoopDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ ShaderModel NoopDriver::getShaderModel() const noexcept {
#endif
}

ShaderLanguage NoopDriver::getShaderLanguage() const noexcept {
return ShaderLanguage::ESSL3;
}

// explicit instantiation of the Dispatcher
template class ConcreteDispatcher<NoopDriver>;

Expand Down
1 change: 1 addition & 0 deletions filament/backend/src/noop/NoopDriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class NoopDriver final : public DriverBase {

private:
ShaderModel getShaderModel() const noexcept final;
ShaderLanguage getShaderLanguage() const noexcept final;

uint64_t nextFakeHandle = 1;

Expand Down
4 changes: 4 additions & 0 deletions filament/backend/src/opengl/OpenGLDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,10 @@ ShaderModel OpenGLDriver::getShaderModel() const noexcept {
return mContext.getShaderModel();
}

ShaderLanguage OpenGLDriver::getShaderLanguage() const noexcept {
return mContext.isES2() ? ShaderLanguage::ESSL1 : ShaderLanguage::ESSL3;
}

// ------------------------------------------------------------------------------------------------
// Change and track GL state
// ------------------------------------------------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions filament/backend/src/opengl/OpenGLDriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ class OpenGLDriver final : public DriverBase {
}

ShaderModel getShaderModel() const noexcept final;
ShaderLanguage getShaderLanguage() const noexcept final;

/*
* Driver interface
Expand Down
5 changes: 5 additions & 0 deletions filament/backend/src/vulkan/VulkanDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "VulkanHandles.h"
#include "VulkanMemory.h"
#include "VulkanTexture.h"
#include "backend/DriverEnums.h"
#include "memory/ResourceManager.h"
#include "memory/ResourcePointer.h"

Expand Down Expand Up @@ -295,6 +296,10 @@ ShaderModel VulkanDriver::getShaderModel() const noexcept {
#endif
}

ShaderLanguage VulkanDriver::getShaderLanguage() const noexcept {
return ShaderLanguage::SPIRV;
}

void VulkanDriver::terminate() {
// Flush and wait here to make sure all queued commands are executed and resources that are tied
// to those commands are no longer referenced.
Expand Down
1 change: 1 addition & 0 deletions filament/backend/src/vulkan/VulkanDriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ class VulkanDriver final : public DriverBase {
Dispatcher getDispatcher() const noexcept final;

ShaderModel getShaderModel() const noexcept final;
ShaderLanguage getShaderLanguage() const noexcept final;

template<typename T>
friend class ConcreteDispatcher;
Expand Down
44 changes: 22 additions & 22 deletions filament/src/details/Engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -706,28 +706,6 @@ int FEngine::loop() {
}
}

#if FILAMENT_ENABLE_MATDBG
#ifdef __ANDROID__
const char* portString = "8081";
#else
const char* portString = getenv("FILAMENT_MATDBG_PORT");
#endif
if (portString != nullptr) {
const int port = atoi(portString);
debug.server = new matdbg::DebugServer(mBackend, port);

// Sometimes the server can fail to spin up (e.g. if the above port is already in use).
// When this occurs, carry onward, developers can look at civetweb.txt for details.
if (!debug.server->isReady()) {
delete debug.server;
debug.server = nullptr;
} else {
debug.server->setEditCallback(FMaterial::onEditCallback);
debug.server->setQueryCallback(FMaterial::onQueryCallback);
}
}
#endif

JobSystem::setThreadName("FEngine::loop");
JobSystem::setThreadPriority(JobSystem::Priority::DISPLAY);

Expand All @@ -749,6 +727,28 @@ int FEngine::loop() {
return 0;
}

#if FILAMENT_ENABLE_MATDBG
#ifdef __ANDROID__
const char* portString = "8081";
#else
const char* portString = getenv("FILAMENT_MATDBG_PORT");
#endif
if (portString != nullptr) {
const int port = atoi(portString);
debug.server = new matdbg::DebugServer(mBackend, mDriver->getShaderLanguage(), port);

// Sometimes the server can fail to spin up (e.g. if the above port is already in use).
// When this occurs, carry onward, developers can look at civetweb.txt for details.
if (!debug.server->isReady()) {
delete debug.server;
debug.server = nullptr;
} else {
debug.server->setEditCallback(FMaterial::onEditCallback);
debug.server->setQueryCallback(FMaterial::onQueryCallback);
}
}
#endif

while (true) {
if (!execute()) {
break;
Expand Down
12 changes: 2 additions & 10 deletions filament/src/details/Engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -252,20 +252,12 @@ class FEngine : public Engine {
// Return a vector of shader languages, in order of preference.
utils::FixedCapacityVector<backend::ShaderLanguage> getShaderLanguage() const noexcept {
switch (mBackend) {
case Backend::DEFAULT:
case Backend::NOOP:
default:
return { backend::ShaderLanguage::ESSL3 };
case Backend::OPENGL:
return { getDriver().getFeatureLevel() == FeatureLevel::FEATURE_LEVEL_0
? backend::ShaderLanguage::ESSL1
: backend::ShaderLanguage::ESSL3 };
case Backend::VULKAN:
return { backend::ShaderLanguage::SPIRV };
return { getDriver().getShaderLanguage() };
case Backend::METAL:
const auto& lang = mConfig.preferredShaderLanguage;
if (lang == Config::ShaderLanguage::MSL) {
return { backend::ShaderLanguage::MSL, backend::ShaderLanguage::METAL_LIBRARY };
return { backend::ShaderLanguage::MSL, backend::ShaderLanguage::METAL_LIBRARY};
}
return { backend::ShaderLanguage::METAL_LIBRARY, backend::ShaderLanguage::MSL };
}
Expand Down
3 changes: 2 additions & 1 deletion libs/matdbg/include/matdbg/DebugServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class DebugServer {
static std::string_view const kSuccessHeader;
static std::string_view const kErrorHeader;

DebugServer(backend::Backend backend, int port);
DebugServer(backend::Backend backend, backend::ShaderLanguage shaderLanguage, int port);
~DebugServer();

/**
Expand Down Expand Up @@ -97,6 +97,7 @@ class DebugServer {
const char* newShaderContent, size_t newShaderLength);

const backend::Backend mBackend;
const backend::ShaderLanguage mShaderLanguage;

CivetServer* mServer;

Expand Down
4 changes: 2 additions & 2 deletions libs/matdbg/include/matdbg/JsonWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ class JsonWriter {
// The array is of the form [ backend, shaderIndex0, shaderIndex1, ... ] where each
// shader index is an active variant. Each bit in the activeVariants bitmask
// represents one of the possible variant combinations.
bool writeActiveInfo(const filaflat::ChunkContainer& package, backend::Backend backend,
VariantList activeVariants);
bool writeActiveInfo(const filaflat::ChunkContainer& package,
backend::ShaderLanguage shaderLanguage, VariantList activeVariants);

private:
utils::CString mJsonString;
Expand Down
5 changes: 4 additions & 1 deletion libs/matdbg/include/matdbg/ShaderReplacer.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,13 @@ namespace matdbg {
// in a manner similar to ShaderExtractor.
class ShaderReplacer {
public:
ShaderReplacer(backend::Backend backend, const void* data, size_t size);
ShaderReplacer(backend::Backend backend, backend::ShaderLanguage language,
const void* data, size_t size);
~ShaderReplacer();
bool replaceShaderSource(backend::ShaderModel shaderModel, Variant variant,
backend::ShaderStage stage, const char* sourceString, size_t stringLength);
const uint8_t* getEditedPackage() const;
filamat::ChunkType getMaterialTag() const noexcept;
size_t getEditedSize() const;
private:
bool replaceSpirv(backend::ShaderModel shaderModel, Variant variant,
Expand All @@ -42,6 +44,7 @@ class ShaderReplacer {
filaflat::ChunkContainer mOriginalPackage;
filaflat::ChunkContainer* mEditedPackage = nullptr;
filamat::ChunkType mMaterialTag = filamat::ChunkType::Unknown;
filamat::ChunkType mDeleteTag = filamat::ChunkType::Unknown;
filamat::ChunkType mDictionaryTag = filamat::ChunkType::Unknown;
};

Expand Down
22 changes: 16 additions & 6 deletions libs/matdbg/src/ApiHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ bool ApiHandler::handleGetApiShader(struct mg_connection* conn,
}

std::string_view const glsl("glsl");
std::string_view const essl3("essl3");
std::string_view const essl1("essl1");
std::string_view const msl("msl");
std::string_view const spirv("spirv");
size_t const qlength = strlen(request->query_string);
Expand All @@ -109,12 +111,20 @@ bool ApiHandler::handleGetApiShader(struct mg_connection* conn,
}

if (glindex[0]) {
if (language != glsl) {
return softError("Only GLSL is supported.");
ChunkType chunkType;
ShaderLanguage shaderLanguage;
if (language == essl3) {
chunkType = ChunkType::MaterialGlsl;
shaderLanguage = ShaderLanguage::ESSL3;
} else if (language == essl1) {
chunkType = ChunkType::MaterialEssl1;
shaderLanguage = ShaderLanguage::ESSL1;
} else {
return softError("Only essl3 and essl1 are supported.");
}

FixedCapacityVector<ShaderInfo> info(getShaderCount(package, ChunkType::MaterialGlsl));
if (!getShaderInfo(package, info.data(), ChunkType::MaterialGlsl)) {
FixedCapacityVector<ShaderInfo> info(getShaderCount(package, chunkType));
if (!getShaderInfo(package, info.data(), chunkType)) {
return error(__LINE__, uri);
}

Expand All @@ -123,7 +133,7 @@ bool ApiHandler::handleGetApiShader(struct mg_connection* conn,
return error(__LINE__, uri);
}

ShaderExtractor extractor(ShaderLanguage::ESSL3, result->package, result->packageSize);
ShaderExtractor extractor(shaderLanguage, result->package, result->packageSize);
if (!extractor.parse()) {
return error(__LINE__, uri);
}
Expand Down Expand Up @@ -314,7 +324,7 @@ bool ApiHandler::handleGet(CivetServer* server, struct mg_connection* conn) {
return error(__LINE__, uri);
}
JsonWriter writer;
if (!writer.writeActiveInfo(package, mServer->mBackend, record.activeVariants)) {
if (!writer.writeActiveInfo(package, mServer->mShaderLanguage, record.activeVariants)) {
return error(__LINE__, uri);
}
bool const last = (++index) == mServer->mMaterialRecords.size();
Expand Down
49 changes: 13 additions & 36 deletions libs/matdbg/src/DebugServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,8 @@ class FileRequestHandler : public CivetHandler {
DebugServer* mServer;
};

DebugServer::DebugServer(Backend backend, int port) : mBackend(backend) {
DebugServer::DebugServer(Backend backend, ShaderLanguage shaderLanguage, int port)
: mBackend(backend), mShaderLanguage(shaderLanguage) {

#if !SERVE_FROM_SOURCE_TREE
ASSET_MAP["/index.html"] = {
Expand Down Expand Up @@ -254,47 +255,23 @@ bool DebugServer::handleEditCommand(const MaterialKey& key, backend::Backend api
return error(__LINE__);
}

FixedCapacityVector<ShaderInfo> infos;
size_t shaderCount;
switch (api) {
case backend::Backend::OPENGL: {
shaderCount = getShaderCount(package, ChunkType::MaterialGlsl);
infos.reserve(shaderCount);
infos.resize(shaderCount);
if (!getShaderInfo(package, infos.data(), ChunkType::MaterialGlsl)) {
return error(__LINE__);
}
break;
}
case backend::Backend::VULKAN: {
shaderCount = getShaderCount(package, ChunkType::MaterialSpirv);
infos.reserve(shaderCount);
infos.resize(shaderCount);
if (!getShaderInfo(package, infos.data(), ChunkType::MaterialSpirv)) {
return error(__LINE__);
}
break;
}
case backend::Backend::METAL: {
shaderCount = getShaderCount(package, ChunkType::MaterialMetal);
infos.reserve(shaderCount);
infos.resize(shaderCount);
if (!getShaderInfo(package, infos.data(), ChunkType::MaterialMetal)) {
return error(__LINE__);
}
break;
}
default:
error(__LINE__);
}
ShaderReplacer editor(api, mShaderLanguage, package.getData(), package.getSize());

size_t shaderCount = getShaderCount(package, editor.getMaterialTag());
if (shaderIndex < 0 || shaderIndex >= shaderCount) {
return error(__LINE__);
}

FixedCapacityVector<ShaderInfo> infos;
infos.reserve(shaderCount);
infos.resize(shaderCount);
if (!getShaderInfo(package, infos.data(), editor.getMaterialTag())) {
return error(__LINE__);
}

const ShaderInfo info = infos[shaderIndex];
ShaderReplacer editor(api, package.getData(), package.getSize());
if (!editor.replaceShaderSource(info.shaderModel, info.variant, info.pipelineStage, source, size)) {
if (!editor.replaceShaderSource(info.shaderModel, info.variant, info.pipelineStage, source,
size)) {
return error(__LINE__);
}

Expand Down
Loading

0 comments on commit 125fe7c

Please sign in to comment.