mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-07-08 16:50:44 +00:00
Add support for extended instruction sets
* Implement a few instructions in GLSL.std.450
This commit is contained in:
@@ -99,6 +99,7 @@ set(sources
|
||||
spirv_compile.cpp
|
||||
spirv_compile.h
|
||||
spirv_debug_setup.cpp
|
||||
spirv_debug_glsl450.cpp
|
||||
spirv_debug.cpp
|
||||
spirv_debug.h
|
||||
spirv_reflect.cpp
|
||||
|
||||
@@ -157,6 +157,7 @@
|
||||
<ForcedIncludeFiles>precompiled.h</ForcedIncludeFiles>
|
||||
</ClCompile>
|
||||
<ClCompile Include="spirv_debug.cpp" />
|
||||
<ClCompile Include="spirv_debug_glsl450.cpp" />
|
||||
<ClCompile Include="spirv_debug_setup.cpp" />
|
||||
<ClCompile Include="spirv_disassemble.cpp">
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
|
||||
@@ -145,6 +145,7 @@
|
||||
<ClCompile Include="spirv_processor.cpp" />
|
||||
<ClCompile Include="spirv_debug_setup.cpp" />
|
||||
<ClCompile Include="spirv_debug.cpp" />
|
||||
<ClCompile Include="spirv_debug_glsl450.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\3rdparty\glslang\OGLCompilersDLL\InitializeDll.h">
|
||||
|
||||
@@ -781,6 +781,53 @@ void ThreadState::StepNext(ShaderDebugState *state,
|
||||
break;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Extended instruction set handling
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
case Op::ExtInst:
|
||||
{
|
||||
Id result = Id::fromWord(it.word(2));
|
||||
Id extinst = Id::fromWord(it.word(3));
|
||||
|
||||
if(global.extInsts.find(extinst) == global.extInsts.end())
|
||||
{
|
||||
RDCERR("Unknown extended instruction set %u", extinst.value());
|
||||
break;
|
||||
}
|
||||
|
||||
const ExtInstDispatcher &dispatch = global.extInsts[extinst];
|
||||
|
||||
// ignore nonsemantic instructions
|
||||
if(dispatch.nonsemantic)
|
||||
break;
|
||||
|
||||
uint32_t instruction = it.word(4);
|
||||
|
||||
if(instruction >= dispatch.functions.size())
|
||||
{
|
||||
RDCERR("Unsupported instruction %u in set %s (only %zu instructions defined)", instruction,
|
||||
dispatch.name.c_str(), dispatch.functions.size());
|
||||
break;
|
||||
}
|
||||
|
||||
if(dispatch.functions[instruction] == NULL)
|
||||
{
|
||||
RDCWARN("Unimplemented extended instruction %s::%s", dispatch.name.c_str(),
|
||||
dispatch.names[instruction].c_str());
|
||||
break;
|
||||
}
|
||||
|
||||
rdcarray<Id> params;
|
||||
for(size_t i = 5; i < it.size(); i++)
|
||||
params.push_back(Id::fromWord(it.word(i)));
|
||||
|
||||
SetDst(state, result, dispatch.functions[instruction](*this, params));
|
||||
break;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Comparison opcodes
|
||||
|
||||
@@ -58,12 +58,28 @@ public:
|
||||
uint32_t component) = 0;
|
||||
};
|
||||
|
||||
struct ThreadState;
|
||||
|
||||
typedef ShaderVariable (*ExtInstImpl)(ThreadState &, const rdcarray<Id> &);
|
||||
|
||||
struct ExtInstDispatcher
|
||||
{
|
||||
rdcstr name;
|
||||
bool nonsemantic = false;
|
||||
rdcarray<rdcstr> names;
|
||||
rdcarray<ExtInstImpl> functions;
|
||||
};
|
||||
|
||||
void ConfigureGLSLStd450(ExtInstDispatcher &extinst);
|
||||
|
||||
struct GlobalState
|
||||
{
|
||||
public:
|
||||
GlobalState() {}
|
||||
// allocated storage for opaque uniform blocks, does not change over the course of debugging
|
||||
rdcarray<ShaderVariable> constantBlocks;
|
||||
|
||||
SparseIdMap<ExtInstDispatcher> extInsts;
|
||||
};
|
||||
|
||||
struct StackFrame
|
||||
@@ -132,8 +148,9 @@ struct ThreadState
|
||||
uint32_t workgroupIndex;
|
||||
bool done;
|
||||
|
||||
private:
|
||||
const ShaderVariable &GetSrc(Id id);
|
||||
|
||||
private:
|
||||
void SetDst(ShaderDebugState *state, Id id, const ShaderVariable &val);
|
||||
void ProcessScopeChange(ShaderDebugState &state, const rdcarray<Id> &oldLive,
|
||||
const rdcarray<Id> &newLive);
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2020 Baldur Karlsson
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#include "spirv_debug.h"
|
||||
#include <math.h>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define finite _finite
|
||||
#endif
|
||||
|
||||
namespace rdcspv
|
||||
{
|
||||
namespace glsl
|
||||
{
|
||||
#define CHECK_PARAMS(n) \
|
||||
if(params.size() != n) \
|
||||
{ \
|
||||
RDCERR("Unexpected number of parameters (%zu) to %s, expected %u", params.size(), \
|
||||
__PRETTY_FUNCTION_SIGNATURE__, n); \
|
||||
return ShaderVariable(); \
|
||||
}
|
||||
|
||||
ShaderVariable FAbs(ThreadState &state, const rdcarray<Id> ¶ms)
|
||||
{
|
||||
CHECK_PARAMS(1);
|
||||
|
||||
ShaderVariable var = state.GetSrc(params[0]);
|
||||
|
||||
for(uint32_t c = 0; c < var.columns; c++)
|
||||
var.value.fv[c] = fabs(var.value.fv[c]);
|
||||
|
||||
return var;
|
||||
}
|
||||
|
||||
ShaderVariable Floor(ThreadState &state, const rdcarray<Id> ¶ms)
|
||||
{
|
||||
CHECK_PARAMS(1);
|
||||
|
||||
ShaderVariable var = state.GetSrc(params[0]);
|
||||
|
||||
for(uint32_t c = 0; c < var.columns; c++)
|
||||
var.value.fv[c] = floor(var.value.fv[c]);
|
||||
|
||||
return var;
|
||||
}
|
||||
|
||||
ShaderVariable Pow(ThreadState &state, const rdcarray<Id> ¶ms)
|
||||
{
|
||||
CHECK_PARAMS(2);
|
||||
|
||||
ShaderVariable var = state.GetSrc(params[0]);
|
||||
ShaderVariable y = state.GetSrc(params[1]);
|
||||
|
||||
for(uint32_t c = 0; c < var.columns; c++)
|
||||
var.value.fv[c] = powf(var.value.fv[c], y.value.fv[c]);
|
||||
|
||||
return var;
|
||||
}
|
||||
|
||||
ShaderVariable FMix(ThreadState &state, const rdcarray<Id> ¶ms)
|
||||
{
|
||||
CHECK_PARAMS(3);
|
||||
|
||||
ShaderVariable var = state.GetSrc(params[0]);
|
||||
ShaderVariable y = state.GetSrc(params[1]);
|
||||
ShaderVariable a = state.GetSrc(params[2]);
|
||||
|
||||
for(uint32_t c = 0; c < var.columns; c++)
|
||||
{
|
||||
float xf = var.value.fv[c];
|
||||
float yf = y.value.fv[c];
|
||||
float af = a.value.fv[c];
|
||||
|
||||
var.value.fv[c] = xf * (1 - af) + yf * af;
|
||||
}
|
||||
|
||||
return var;
|
||||
}
|
||||
|
||||
ShaderVariable Normalize(ThreadState &state, const rdcarray<Id> ¶ms)
|
||||
{
|
||||
CHECK_PARAMS(1);
|
||||
|
||||
ShaderVariable var = state.GetSrc(params[0]);
|
||||
|
||||
float sqrlength = 0.0f;
|
||||
|
||||
for(uint32_t c = 0; c < var.columns; c++)
|
||||
sqrlength += (var.value.fv[c] * var.value.fv[c]);
|
||||
|
||||
float invlength = 1.0f / sqrt(sqrlength);
|
||||
|
||||
for(uint32_t c = 0; c < var.columns; c++)
|
||||
var.value.fv[c] *= invlength;
|
||||
|
||||
return var;
|
||||
}
|
||||
|
||||
ShaderVariable Cross(ThreadState &state, const rdcarray<Id> ¶ms)
|
||||
{
|
||||
CHECK_PARAMS(2);
|
||||
|
||||
ShaderVariable x = state.GetSrc(params[0]);
|
||||
ShaderVariable y = state.GetSrc(params[1]);
|
||||
|
||||
RDCASSERT(x.columns == 3 && y.columns == 3, x.columns, y.columns);
|
||||
|
||||
ShaderVariable var = x;
|
||||
|
||||
var.value.fv[0] = x.value.fv[1] * y.value.fv[2] - y.value.fv[1] * x.value.fv[2];
|
||||
var.value.fv[1] = x.value.fv[2] * y.value.fv[0] - y.value.fv[2] * x.value.fv[0];
|
||||
var.value.fv[2] = x.value.fv[0] * y.value.fv[1] - y.value.fv[0] * x.value.fv[1];
|
||||
|
||||
return var;
|
||||
}
|
||||
}; // namespace glsl
|
||||
|
||||
void ConfigureGLSLStd450(ExtInstDispatcher &extinst)
|
||||
{
|
||||
extinst.names.resize((size_t)GLSLstd450::Max);
|
||||
for(size_t i = 0; i < extinst.names.size(); i++)
|
||||
extinst.names[i] = ToStr(GLSLstd450(i));
|
||||
|
||||
extinst.functions.resize(extinst.names.size());
|
||||
|
||||
#define EXT(func) extinst.functions[(uint32_t)GLSLstd450::func] = &glsl::func;
|
||||
EXT(FAbs);
|
||||
EXT(Floor);
|
||||
EXT(Pow);
|
||||
EXT(FMix);
|
||||
EXT(Cross);
|
||||
EXT(Normalize);
|
||||
}
|
||||
}; // namespace rdcspv
|
||||
@@ -200,6 +200,38 @@ ShaderDebugTrace *Debugger::BeginDebug(DebugAPIWrapper *apiWrapper, const Shader
|
||||
}
|
||||
}
|
||||
|
||||
for(auto it = extSets.begin(); it != extSets.end(); it++)
|
||||
{
|
||||
Id id = it->first;
|
||||
const rdcstr &setname = it->second;
|
||||
|
||||
if(setname == "GLSL.std.450")
|
||||
{
|
||||
ExtInstDispatcher extinst;
|
||||
|
||||
extinst.name = setname;
|
||||
|
||||
ConfigureGLSLStd450(extinst);
|
||||
|
||||
global.extInsts[id] = extinst;
|
||||
}
|
||||
else if(setname.beginsWith("NonSemantic."))
|
||||
{
|
||||
ExtInstDispatcher extinst;
|
||||
|
||||
extinst.name = setname;
|
||||
|
||||
extinst.nonsemantic = true;
|
||||
|
||||
global.extInsts[id] = extinst;
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCERR("Unsupported extended instruction set: %s", setname.c_str());
|
||||
return new ShaderDebugTrace;
|
||||
}
|
||||
}
|
||||
|
||||
for(const rdcstr &e : extensions)
|
||||
{
|
||||
if(e == "SPV_GOOGLE_decorate_string" || e == "SPV_GOOGLE_hlsl_functionality1")
|
||||
|
||||
@@ -192,6 +192,78 @@ void main()
|
||||
Color = dFdyFine(vec4(inpos, inposIncreased));
|
||||
break;
|
||||
}
|
||||
case 13:
|
||||
{
|
||||
Color = vec4(abs(posone*2.5f), abs(negone*2.5f), abs(zerof*2.5f), 1.0f);
|
||||
break;
|
||||
}
|
||||
case 14:
|
||||
{
|
||||
Color = vec4(pow(posone*2.5f, posone*1.3f), pow(posone*2.5f, posone*0.45f),
|
||||
pow(vec2(posone*2.5f, posone*1.3f), vec2(posone*0.9f, posone*8.5f)));
|
||||
break;
|
||||
}
|
||||
case 15:
|
||||
{
|
||||
Color = vec4(normalize(posone*2.5f), normalize(posone), normalize(negone), 1.0f);
|
||||
break;
|
||||
}
|
||||
case 16:
|
||||
{
|
||||
Color = vec4(normalize(vec2(posone*2.5f, negone*1.8f)), normalize(vec2(posone*8.5f, negone*7.1f)));
|
||||
break;
|
||||
}
|
||||
case 17:
|
||||
{
|
||||
Color = vec4(normalize(vec3(posone*2.5f, negone*1.8f, posone*8.5f)), 1.0f);
|
||||
break;
|
||||
}
|
||||
case 18:
|
||||
{
|
||||
Color = normalize(vec4(posone*2.5f, negone*1.8f, posone*8.5f, negone*5.2f));
|
||||
break;
|
||||
}
|
||||
case 19:
|
||||
{
|
||||
Color = vec4(floor(posone*2.5f), floor(posone*2.4f), floor(posone*2.6f), floor(zerof));
|
||||
break;
|
||||
}
|
||||
case 20:
|
||||
{
|
||||
Color = vec4(floor(negone*2.5f), floor(negone*2.4f), floor(negone*2.6f), 1.0f);
|
||||
break;
|
||||
}
|
||||
case 21:
|
||||
{
|
||||
Color = vec4(mix(posone*1.1f, posone*3.3f, 0.5f),
|
||||
mix(posone*1.1f, posone*3.3f, 0.2f),
|
||||
mix(posone*1.1f, posone*3.3f, 0.8f),
|
||||
1.0f);
|
||||
break;
|
||||
}
|
||||
case 22:
|
||||
{
|
||||
Color = vec4(mix(posone*1.1f, posone*3.3f, 1.5f),
|
||||
mix(posone*1.1f, posone*3.3f, -0.3f),
|
||||
0.0f,
|
||||
1.0f);
|
||||
break;
|
||||
}
|
||||
case 23:
|
||||
{
|
||||
Color = vec4(mix(posone*3.3f, posone*1.1f, 0.5f),
|
||||
mix(posone*3.3f, posone*1.1f, 0.2f),
|
||||
mix(posone*3.3f, posone*1.1f, 0.8f),
|
||||
1.0f);
|
||||
break;
|
||||
}
|
||||
case 24:
|
||||
{
|
||||
vec3 a = vec3(posone*2.5f, negone*1.8f, posone*8.5f);
|
||||
vec3 b = vec3(negone*6.3f, posone*3.2f, negone*0.4f);
|
||||
Color = vec4(cross(a, b), 1.0f);
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user