diff --git a/filament/src/details/Engine.cpp b/filament/src/details/Engine.cpp index 01cc8ec9be95..741e2b3b621f 100644 --- a/filament/src/details/Engine.cpp +++ b/filament/src/details/Engine.cpp @@ -751,7 +751,8 @@ int FEngine::loop() { #endif if (portString != nullptr) { const int port = atoi(portString); - debug.server = new matdbg::DebugServer(mBackend, mDriver->getShaderLanguage(), port); + debug.server = new matdbg::DebugServer(mBackend, mDriver->getShaderLanguage(), + matdbg::DbgShaderModel((uint8_t) mDriver->getShaderModel()), 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. diff --git a/libs/matdbg/include/matdbg/DebugServer.h b/libs/matdbg/include/matdbg/DebugServer.h index 86aaa79bd10a..272d68ab28f0 100644 --- a/libs/matdbg/include/matdbg/DebugServer.h +++ b/libs/matdbg/include/matdbg/DebugServer.h @@ -41,6 +41,13 @@ struct MaterialRecord { VariantList activeVariants; }; +// Matches DriverEnums' ShaderModel +enum class DbgShaderModel { + MOBILE = 1, //!< Mobile level functionality + DESKTOP = 2, //!< Desktop level functionality + MATINFO = 10, //!< To indicate debug server is running from matinfo +}; + /** * Server-side material debugger. * @@ -52,7 +59,8 @@ class DebugServer { static std::string_view const kSuccessHeader; static std::string_view const kErrorHeader; - DebugServer(backend::Backend backend, backend::ShaderLanguage shaderLanguage, int port); + DebugServer(backend::Backend backend, backend::ShaderLanguage shaderLanguage, + DbgShaderModel perferredShaderModel, int port); ~DebugServer(); /** @@ -85,10 +93,13 @@ class DebugServer { bool isReady() const { return mServer; } private: + // called from ApiHandler MaterialRecord const* getRecord(const MaterialKey& key) const; + // called from ApiHandler void updateActiveVariants(); + // called from ApiHandler /** * Replaces the entire content of a particular shader variant. The given shader index uses the * same ordering that the variants have within the package. @@ -96,8 +107,9 @@ class DebugServer { bool handleEditCommand(const MaterialKey& mat, backend::Backend api, int shaderIndex, const char* newShaderContent, size_t newShaderLength); - const backend::Backend mBackend; - const backend::ShaderLanguage mShaderLanguage; + backend::Backend const mBackend; + backend::ShaderLanguage const mShaderLanguage; + DbgShaderModel const mPreferredShaderModel; CivetServer* mServer; diff --git a/libs/matdbg/include/matdbg/JsonWriter.h b/libs/matdbg/include/matdbg/JsonWriter.h index 4291f6f74926..f1ff7f7aaea9 100644 --- a/libs/matdbg/include/matdbg/JsonWriter.h +++ b/libs/matdbg/include/matdbg/JsonWriter.h @@ -17,6 +17,8 @@ #ifndef MATDBG_JSONWRITER_H #define MATDBG_JSONWRITER_H +#include + #include #include @@ -47,7 +49,8 @@ class JsonWriter { // 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::ShaderLanguage shaderLanguage, VariantList activeVariants); + backend::ShaderLanguage shaderLanguage, DbgShaderModel shaderModel, + VariantList activeVariants); private: utils::CString mJsonString; diff --git a/libs/matdbg/src/ApiHandler.cpp b/libs/matdbg/src/ApiHandler.cpp index 3c53265317cf..fb3c0673aa99 100644 --- a/libs/matdbg/src/ApiHandler.cpp +++ b/libs/matdbg/src/ApiHandler.cpp @@ -332,7 +332,8 @@ bool ApiHandler::handleGet(CivetServer* server, struct mg_connection* conn) { return error(__LINE__, uri); } JsonWriter writer; - if (!writer.writeActiveInfo(package, mServer->mShaderLanguage, record.activeVariants)) { + if (!writer.writeActiveInfo(package, mServer->mShaderLanguage, + mServer->mPreferredShaderModel, record.activeVariants)) { return error(__LINE__, uri); } bool const last = (++index) == mServer->mMaterialRecords.size(); @@ -356,6 +357,18 @@ bool ApiHandler::handleGet(CivetServer* server, struct mg_connection* conn) { return true; } + auto writeMaterialRecord = [&](JsonWriter* writer, MaterialRecord const* record) { + ChunkContainer package(record->package, record->packageSize); + if (!package.parse()) { + return error(__LINE__, uri); + } + + if (!writer->writeMaterialInfo(package)) { + return error(__LINE__, uri); + } + return true; + }; + if (uri == "/api/materials") { std::unique_lock const lock(mServer->mMaterialRecordsMutex); mg_printf(conn, kSuccessHeader.data(), "application/json"); @@ -363,17 +376,11 @@ bool ApiHandler::handleGet(CivetServer* server, struct mg_connection* conn) { int index = 0; for (auto const& record: mServer->mMaterialRecords) { bool const last = (++index) == mServer->mMaterialRecords.size(); - - ChunkContainer package(record.second.package, record.second.packageSize); - if (!package.parse()) { - return error(__LINE__, uri); - } - + auto const& mat = record.second; JsonWriter writer; - if (!writer.writeMaterialInfo(package)) { - return error(__LINE__, uri); + if (!writeMaterialRecord(&writer, &mat)) { + return false; } - mg_printf(conn, "{ \"matid\": \"%8.8x\", %s } %s", record.first, writer.getJsonString(), last ? "" : ","); } @@ -386,15 +393,9 @@ bool ApiHandler::handleGet(CivetServer* server, struct mg_connection* conn) { if (!result) { return error(__LINE__, uri); } - - ChunkContainer package(result->package, result->packageSize); - if (!package.parse()) { - return error(__LINE__, uri); - } - JsonWriter writer; - if (!writer.writeMaterialInfo(package)) { - return error(__LINE__, uri); + if (!writeMaterialRecord(&writer, result)) { + return false; } mg_printf(conn, kSuccessHeader.data(), "application/json"); mg_printf(conn, "{ %s }", writer.getJsonString()); diff --git a/libs/matdbg/src/DebugServer.cpp b/libs/matdbg/src/DebugServer.cpp index d75952728b8e..9285bc38c589 100644 --- a/libs/matdbg/src/DebugServer.cpp +++ b/libs/matdbg/src/DebugServer.cpp @@ -122,8 +122,11 @@ class FileRequestHandler : public CivetHandler { DebugServer* mServer; }; -DebugServer::DebugServer(Backend backend, ShaderLanguage shaderLanguage, int port) - : mBackend(backend), mShaderLanguage(shaderLanguage) { +DebugServer::DebugServer(Backend backend, ShaderLanguage shaderLanguage, + DbgShaderModel perferredShaderModel, int port) + : mBackend(backend), + mShaderLanguage(shaderLanguage), + mPreferredShaderModel(perferredShaderModel) { #if !SERVE_FROM_SOURCE_TREE ASSET_MAP["/index.html"] = { diff --git a/libs/matdbg/src/JsonWriter.cpp b/libs/matdbg/src/JsonWriter.cpp index 2a22eaeae2e9..7a5409927b5e 100644 --- a/libs/matdbg/src/JsonWriter.cpp +++ b/libs/matdbg/src/JsonWriter.cpp @@ -232,7 +232,7 @@ size_t JsonWriter::getJsonSize() const { } bool JsonWriter::writeActiveInfo(const filaflat::ChunkContainer& package, - ShaderLanguage shaderLanguage, VariantList activeVariants) { + ShaderLanguage shaderLanguage, DbgShaderModel shaderModel, VariantList activeVariants) { vector shaders; ostringstream json; json << "[\""; @@ -260,7 +260,20 @@ bool JsonWriter::writeActiveInfo(const filaflat::ChunkContainer& package, shaders.resize(getShaderCount(package, chunkType)); getShaderInfo(package, shaders.data(), chunkType); + json << "\", \""; + switch (shaderModel) { + case DbgShaderModel::DESKTOP: + json << toString(ShaderModel::DESKTOP); + break; + case DbgShaderModel::MOBILE: + json << toString(ShaderModel::MOBILE); + break; + case DbgShaderModel::MATINFO: + json << "matinfo"; + break; + } json << "\""; + for (size_t variant = 0; variant < activeVariants.size(); variant++) { if (activeVariants[variant]) { json << ", " << variant; diff --git a/libs/matdbg/src/ShaderInfo.cpp b/libs/matdbg/src/ShaderInfo.cpp index 632c20d71177..320e1b383a05 100644 --- a/libs/matdbg/src/ShaderInfo.cpp +++ b/libs/matdbg/src/ShaderInfo.cpp @@ -50,7 +50,6 @@ size_t getShaderCount(const ChunkContainer& container, ChunkType type) { return shaderCount; } - bool getShaderInfo(const ChunkContainer& container, ShaderInfo* info, ChunkType chunkType) { if (!container.hasChunk(chunkType)) { return true; diff --git a/libs/matdbg/web/api.js b/libs/matdbg/web/api.js index a6e62f788d52..79eedf78bc59 100644 --- a/libs/matdbg/web/api.js +++ b/libs/matdbg/web/api.js @@ -72,10 +72,9 @@ async function queryActiveShaders() { const actives = {}; for (matid in activeVariants) { const backend = activeVariants[matid][0]; - const variants = activeVariants[matid].slice(1); - actives[matid] = { - backend, variants - }; + const shaderModel = activeVariants[matid][1]; + const variants = activeVariants[matid].slice(2); + actives[matid] = { backend, shaderModel, variants }; } return actives; } diff --git a/libs/matdbg/web/app.js b/libs/matdbg/web/app.js index e9bad73a01eb..56a85d7230f0 100644 --- a/libs/matdbg/web/app.js +++ b/libs/matdbg/web/app.js @@ -59,8 +59,8 @@ const FOREGROUND_COLOR = '#fafafa'; const INACTIVE_COLOR = '#9a9a9a'; const DARKER_INACTIVE_COLOR = '#6f6f6f'; const LIGHTER_INACTIVE_COLOR = '#d9d9d9'; -const UNSELECTED_COLOR = '#dfdfdf'; -const BACKGROUND_COLOR = '#5362e5'; +const UNSELECTED_COLOR = '#d0d0d0'; +const BACKGROUND_COLOR = '#6885c5'; const HOVER_BACKGROUND_COLOR = '#b3c2ff'; const CODE_VIEWER_BOTTOM_ROW_HEIGHT = 60; const REGULAR_FONT_SIZE = 12; @@ -343,7 +343,7 @@ class MenuSection extends LitElement { color: ${unsafeCSS(UNSELECTED_COLOR)}; } .section-title { - font-size: 16px; + font-size: 20px; color: ${unsafeCSS(UNSELECTED_COLOR)}; cursor: pointer; } @@ -365,6 +365,9 @@ class MenuSection extends LitElement { align-items: center; justify-content: space-between; } + .expanded-title { + color: ${unsafeCSS(FOREGROUND_COLOR)}; + } `; } @@ -380,9 +383,10 @@ class MenuSection extends LitElement { render() { const expandedIcon = this.showing ? '๏ผ' : '๏ผ‹'; const slot = (() => html``)(); + const epandedTitleClass = this.showing ? 'expanded-title' : ''; return html`
-
+
${this.title} ${expandedIcon}

@@ -460,6 +464,7 @@ class AdvancedOptions extends LitElement { static get properties() { return { currentBackend: {type: String, attribute: 'current-backend'}, + currentShaderModel: {type: String, attribute: 'current-shader-model'}, hideInactiveVariants: {type: Boolean, attribute: 'hide-inactive-variants'}, availableBackends: {type: Array, state: true}, }; @@ -478,6 +483,7 @@ class AdvancedOptions extends LitElement { flex-direction: column; justify-content: center; align-items: flex-start; + margin-bottom: 6px; } .borderless { border: 1px solid rgba(0,0,0,0); @@ -570,7 +576,7 @@ class AdvancedOptions extends LitElement { return html`
Current Backend
-
+ ${div}
@@ -578,6 +584,9 @@ class AdvancedOptions extends LitElement { } _hideInactiveVariantsOption() { + if (this.currentShaderModel == 'matinfo') { + return null; + } const onChange = (ev) => { this.dispatchEvent( new CustomEvent( @@ -585,7 +594,7 @@ class AdvancedOptions extends LitElement { {detail: null, bubbles: true, composed: true})); } return html` -
+
${languagesDiv}
`; } - _buildShaderDiv(showAllShaders) { + _buildShaderDiv() { if (!this.variants) { return null; } + const isMatinfo = this.currentShaderModel == 'matinfo'; let variants = this.variants .sort((a, b) => { @@ -798,7 +809,10 @@ class MaterialSidePanel extends LitElement { if (b.active && !a.active) return 1; return 0; }) - .filter((variant) => (!this.hideInactiveVariants || variant.shader.active)) + .filter(variant => (!this.hideInactiveVariants || variant.shader.active)) + .filter(variant => ( + isMatinfo || variant.shader.shaderModel == this.currentShaderModel + )) .map((variant) => { let divClass = 'material_variant_language'; const shaderIndex = +variant.shader.index; @@ -807,7 +821,7 @@ class MaterialSidePanel extends LitElement { if (isVariantSelected) { divClass += ' selected'; } - if (!isActive) { + if (!isActive && !isMatinfo) { divClass += ' inactive'; } const onClickVariant = this._handleVariantClick.bind(this, shaderIndex); @@ -816,11 +830,18 @@ class MaterialSidePanel extends LitElement { if (vstring.length > 0) { vstring = `[${vstring}]`; } + const shaderModelSymbol = { + 'desktop': '๐Ÿ„ณ ', + 'mobile': '๐Ÿ„ผ ', + }; + let languagesDiv = isVariantSelected ? this._buildLanguagesDiv(isActive) : null; - const stage = (isVariantSelected ? 'โ— ' : '') + variant.shader.pipelineStage; + const stage = + (isMatinfo ? shaderModelSymbol[variant.shader.shaderModel] : '') + + (variant.shader.pipelineStage.indexOf('vertex') >=0 ? '๐•ert' : '๐”ฝrag'); return html`
-
${stage} ${vstring}
+
${stage}  ${vstring}
${languagesDiv ?? nothing} ` @@ -829,6 +850,7 @@ class MaterialSidePanel extends LitElement { } render() { + const isMatinfo = this.currentShaderModel == 'matinfo'; const sections = (title, domain) => { const mats = this.materials .filter((m) => m.domain == domain) @@ -844,14 +866,12 @@ class MaterialSidePanel extends LitElement { const isMaterialSelected = mat.matid === this.currentMaterial; if (isMaterialSelected) { divClass += ' selected'; - // If we are looking at an inactive material, show all shaders regardless. - const showAllShaders = !material.active; - shaderDiv = this._buildShaderDiv(showAllShaders); + shaderDiv = this._buildShaderDiv(); } - if (!material.active) { + if (!material.active && !isMatinfo) { divClass += " inactive"; } - const matName = (isMaterialSelected ? 'โ— ' : '') + mat.name; + const matName = mat.name; return html`
${matName} @@ -868,6 +888,7 @@ class MaterialSidePanel extends LitElement { (() => html` `)(); @@ -875,7 +896,7 @@ class MaterialSidePanel extends LitElement { return html`
-
matdbg
+
${isMatinfo ? 'matinfo' : 'matdbg'}
${sections("Surface", "surface") ?? nothing} ${sections("Post-processing", "postpro") ?? nothing} @@ -968,6 +989,7 @@ class MatdbgViewer extends LitElement { this.currentMaterial = null; this.currentLanguage = null; this.currentBackend = null; + this.currentShaderModel = null; this.hideInactiveVariants = false; this.init(); @@ -1038,6 +1060,7 @@ class MatdbgViewer extends LitElement { // Each material has a list of variants compiled for it, this index tracks a position in the list. currentShaderIndex: {type: Number, state: true}, currentBackend: {type: String, state: true}, + currentShaderModel: {type: String, state: true}, codeViewerExpectedWidth: {type: Number, state: true}, codeViewerExpectedHeight: {type: Number, state: true}, @@ -1084,7 +1107,6 @@ class MatdbgViewer extends LitElement { shader.modified = false; this.database = this.database; } - // Size of the editor will be adjusted due to the code being loaded, we try to // fit the editor again by calling the resize signal. setTimeout(this._onResize.bind(this), 700); @@ -1108,22 +1130,29 @@ class MatdbgViewer extends LitElement { } } if (_validDict(this.activeShaders)) { - let backends = {}; + let setBackend = null; + let setShaderModel = null; for (let matid in this.activeShaders) { const backend = this.activeShaders[matid].backend; - if (backend in backends) { - backends[backend] = backends[backend] + 1; - } else { - backends[backend] = 1; + if (!setBackend && backend) { + setBackend = backend; } + const shaderModel = this.activeShaders[matid].shaderModel; + if (!setShaderModel && shaderModel) { + setShaderModel = shaderModel; + } + } + if (this.currentBackend != setBackend) { + this.currentBackend = setBackend; } - let backendList = Object.keys(backends); - if (backendList.length > 0) { - this.currentBackend = backendList[0]; + if (this.currentShaderModel != setShaderModel) { + this.currentShaderModel = setShaderModel; } - } else if (!this.currentBackend) { + + } else if (!this.currentBackend || !this.currentShaderModel) { // Make a guess on the backend if one wasn't from activeShaders. this.currentBackend = guessBackend(); + this.currentShaderModel = 'matinfo'; } this._sidepanel.database = this.database; @@ -1155,6 +1184,7 @@ class MatdbgViewer extends LitElement { current-shader-index="${this.currentShaderIndex}" current-material="${this.currentMaterial}" current-backend="${this.currentBackend}" + current-shader-model="${this.currentShaderModel}" ?hide-inactive-variants="${this.hideInactiveVariants}" >