mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-09-08 06:45:49 +00:00
Account for pipeline specialisation constants when reflecting shaders
This commit is contained in:
@@ -109,6 +109,8 @@ void ConstantBufferPreviewer::OnEventChanged(uint32_t eventId)
|
||||
|
||||
ResourceId prevShader = m_shader;
|
||||
|
||||
m_pipe = m_stage == ShaderStage::Compute ? m_Ctx.CurPipelineState().GetComputePipelineObject()
|
||||
: m_Ctx.CurPipelineState().GetGraphicsPipelineObject();
|
||||
m_shader = m_Ctx.CurPipelineState().GetShader(m_stage);
|
||||
QString entryPoint = m_Ctx.CurPipelineState().GetShaderEntryPoint(m_stage);
|
||||
const ShaderReflection *reflection = m_Ctx.CurPipelineState().GetShaderReflection(m_stage);
|
||||
@@ -153,7 +155,7 @@ void ConstantBufferPreviewer::OnEventChanged(uint32_t eventId)
|
||||
{
|
||||
m_Ctx.Replay().AsyncInvoke([this, prevShader, entryPoint, offs, wasEmpty](IReplayController *r) {
|
||||
rdcarray<ShaderVariable> vars = r->GetCBufferVariableContents(
|
||||
m_shader, entryPoint.toUtf8().data(), m_slot, m_cbuffer, offs);
|
||||
m_pipe, m_shader, entryPoint.toUtf8().data(), m_slot, m_cbuffer, offs);
|
||||
GUIInvoke::call(this, [this, prevShader, vars, wasEmpty] {
|
||||
|
||||
RDTreeViewExpansionState &prevShaderExpansionState =
|
||||
|
||||
@@ -72,6 +72,7 @@ private:
|
||||
ICaptureContext &m_Ctx;
|
||||
|
||||
ResourceId m_cbuffer;
|
||||
ResourceId m_pipe;
|
||||
ResourceId m_shader;
|
||||
ShaderStage m_stage = ShaderStage::Vertex;
|
||||
uint32_t m_slot = 0;
|
||||
|
||||
@@ -478,10 +478,12 @@ void ResourceInspector::on_viewContents_clicked()
|
||||
// TODO need to let the user choose the entry point
|
||||
}
|
||||
|
||||
// TODO allow choosing parent pipeline?
|
||||
ResourceId pipeid;
|
||||
ResourceId id = m_Resource;
|
||||
ICaptureContext *ctx = &m_Ctx;
|
||||
m_Ctx.Replay().AsyncInvoke([this, ctx, id, entry](IReplayController *r) {
|
||||
ShaderReflection *refl = r->GetShader(id, entry);
|
||||
m_Ctx.Replay().AsyncInvoke([this, ctx, pipeid, id, entry](IReplayController *r) {
|
||||
ShaderReflection *refl = r->GetShader(pipeid, id, entry);
|
||||
|
||||
if(!refl)
|
||||
return;
|
||||
|
||||
@@ -1178,13 +1178,15 @@ only ever have one result (only one entry point per shader).
|
||||
|
||||
DOCUMENT(R"(Retrieve the information about the frame contained in the capture.
|
||||
|
||||
:param ResourceId pipeline: The pipeline state object, if applicable, that this shader is bound to.
|
||||
:param ResourceId shader: The shader to get reflection data for.
|
||||
:param ShaderEntryPoint entry: The entry point within the shader to reflect. May be ignored on some
|
||||
APIs
|
||||
:return: The frame information.
|
||||
:rtype: ShaderReflection
|
||||
)");
|
||||
virtual ShaderReflection *GetShader(ResourceId shader, ShaderEntryPoint entry) = 0;
|
||||
virtual ShaderReflection *GetShader(ResourceId pipeline, ResourceId shader,
|
||||
ShaderEntryPoint entry) = 0;
|
||||
|
||||
DOCUMENT(R"(Retrieve the history of modifications to the selected pixel on the selected texture.
|
||||
|
||||
@@ -1270,6 +1272,7 @@ only ever have one result (only one entry point per shader).
|
||||
DOCUMENT(R"(Retrieve the contents of a constant block by reading from memory or their source
|
||||
otherwise.
|
||||
|
||||
:param ResourceId pipeline: The pipeline state object, if applicable, that this shader is bound to.
|
||||
:param ResourceId shader: The id of the shader to use for metadata.
|
||||
:param str entryPoint: The entry point of the shader being used. In some APIs, this is ignored.
|
||||
:param int cbufslot: The index in the :data:`ShaderReflection.constantBlocks` list to look up.
|
||||
@@ -1279,7 +1282,7 @@ otherwise.
|
||||
:return: The shader variables with their contents.
|
||||
:rtype: ``list`` of :class:`ShaderVariable`
|
||||
)");
|
||||
virtual rdcarray<ShaderVariable> GetCBufferVariableContents(ResourceId shader,
|
||||
virtual rdcarray<ShaderVariable> GetCBufferVariableContents(ResourceId pipeline, ResourceId shader,
|
||||
const char *entryPoint,
|
||||
uint32_t cbufslot, ResourceId buffer,
|
||||
uint64_t offs) = 0;
|
||||
|
||||
@@ -215,8 +215,8 @@ public:
|
||||
{
|
||||
return std::vector<CounterResult>();
|
||||
}
|
||||
void FillCBufferVariables(ResourceId shader, std::string entryPoint, uint32_t cbufSlot,
|
||||
rdcarray<ShaderVariable> &outvars, const bytebuf &data)
|
||||
void FillCBufferVariables(ResourceId pipeline, ResourceId shader, std::string entryPoint,
|
||||
uint32_t cbufSlot, rdcarray<ShaderVariable> &outvars, const bytebuf &data)
|
||||
{
|
||||
}
|
||||
void GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, bytebuf &retData) {}
|
||||
@@ -235,7 +235,10 @@ public:
|
||||
return ResourceId();
|
||||
}
|
||||
rdcarray<ShaderEntryPoint> GetShaderEntryPoints(ResourceId shader) { return {}; }
|
||||
ShaderReflection *GetShader(ResourceId shader, ShaderEntryPoint entry) { return NULL; }
|
||||
ShaderReflection *GetShader(ResourceId pipeline, ResourceId shader, ShaderEntryPoint entry)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
std::vector<std::string> GetDisassemblyTargets() { return {"N/A"}; }
|
||||
std::string DisassembleShader(ResourceId pipeline, const ShaderReflection *refl,
|
||||
const std::string &target)
|
||||
|
||||
@@ -734,15 +734,16 @@ CounterDescription ReplayProxy::DescribeCounter(GPUCounter counterID)
|
||||
|
||||
template <typename ParamSerialiser, typename ReturnSerialiser>
|
||||
void ReplayProxy::Proxied_FillCBufferVariables(ParamSerialiser ¶mser, ReturnSerialiser &retser,
|
||||
ResourceId shader, std::string entryPoint,
|
||||
uint32_t cbufSlot, rdcarray<ShaderVariable> &outvars,
|
||||
const bytebuf &data)
|
||||
ResourceId pipeline, ResourceId shader,
|
||||
std::string entryPoint, uint32_t cbufSlot,
|
||||
rdcarray<ShaderVariable> &outvars, const bytebuf &data)
|
||||
{
|
||||
const ReplayProxyPacket expectedPacket = eReplayProxy_FillCBufferVariables;
|
||||
ReplayProxyPacket packet = eReplayProxy_FillCBufferVariables;
|
||||
|
||||
{
|
||||
BEGIN_PARAMS();
|
||||
SERIALISE_ELEMENT(pipeline);
|
||||
SERIALISE_ELEMENT(shader);
|
||||
SERIALISE_ELEMENT(entryPoint);
|
||||
SERIALISE_ELEMENT(cbufSlot);
|
||||
@@ -753,16 +754,17 @@ void ReplayProxy::Proxied_FillCBufferVariables(ParamSerialiser ¶mser, Return
|
||||
{
|
||||
REMOTE_EXECUTION();
|
||||
if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored)
|
||||
m_Remote->FillCBufferVariables(shader, entryPoint, cbufSlot, outvars, data);
|
||||
m_Remote->FillCBufferVariables(pipeline, shader, entryPoint, cbufSlot, outvars, data);
|
||||
}
|
||||
|
||||
SERIALISE_RETURN(outvars);
|
||||
}
|
||||
|
||||
void ReplayProxy::FillCBufferVariables(ResourceId shader, std::string entryPoint, uint32_t cbufSlot,
|
||||
void ReplayProxy::FillCBufferVariables(ResourceId pipeline, ResourceId shader,
|
||||
std::string entryPoint, uint32_t cbufSlot,
|
||||
rdcarray<ShaderVariable> &outvars, const bytebuf &data)
|
||||
{
|
||||
PROXY_FUNCTION(FillCBufferVariables, shader, entryPoint, cbufSlot, outvars, data);
|
||||
PROXY_FUNCTION(FillCBufferVariables, pipeline, shader, entryPoint, cbufSlot, outvars, data);
|
||||
}
|
||||
|
||||
template <typename ParamSerialiser, typename ReturnSerialiser>
|
||||
@@ -1084,22 +1086,24 @@ rdcarray<ShaderEntryPoint> ReplayProxy::GetShaderEntryPoints(ResourceId id)
|
||||
}
|
||||
|
||||
template <typename ParamSerialiser, typename ReturnSerialiser>
|
||||
ShaderReflection *ReplayProxy::Proxied_GetShader(ParamSerialiser ¶mser, ReturnSerialiser &retser,
|
||||
ResourceId id, ShaderEntryPoint entry)
|
||||
ShaderReflection *ReplayProxy::Proxied_GetShader(ParamSerialiser ¶mser,
|
||||
ReturnSerialiser &retser, ResourceId pipeline,
|
||||
ResourceId shader, ShaderEntryPoint entry)
|
||||
{
|
||||
const ReplayProxyPacket expectedPacket = eReplayProxy_GetShader;
|
||||
ReplayProxyPacket packet = eReplayProxy_GetShader;
|
||||
ShaderReflection *ret = NULL;
|
||||
|
||||
// only consider eventID part of the key on APIs where shaders are mutable
|
||||
ShaderReflKey key(m_APIProps.shadersMutable ? m_EventID : 0, id, entry);
|
||||
ShaderReflKey key(m_APIProps.shadersMutable ? m_EventID : 0, pipeline, shader, entry);
|
||||
|
||||
if(retser.IsReading() && m_ShaderReflectionCache.find(key) != m_ShaderReflectionCache.end())
|
||||
return m_ShaderReflectionCache[key];
|
||||
|
||||
{
|
||||
BEGIN_PARAMS();
|
||||
SERIALISE_ELEMENT(id);
|
||||
SERIALISE_ELEMENT(pipeline);
|
||||
SERIALISE_ELEMENT(shader);
|
||||
SERIALISE_ELEMENT(entry);
|
||||
END_PARAMS();
|
||||
}
|
||||
@@ -1107,7 +1111,7 @@ ShaderReflection *ReplayProxy::Proxied_GetShader(ParamSerialiser ¶mser, Retu
|
||||
{
|
||||
REMOTE_EXECUTION();
|
||||
if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored)
|
||||
ret = m_Remote->GetShader(id, entry);
|
||||
ret = m_Remote->GetShader(pipeline, shader, entry);
|
||||
}
|
||||
|
||||
{
|
||||
@@ -1131,9 +1135,10 @@ ShaderReflection *ReplayProxy::Proxied_GetShader(ParamSerialiser ¶mser, Retu
|
||||
return m_ShaderReflectionCache[key];
|
||||
}
|
||||
|
||||
ShaderReflection *ReplayProxy::GetShader(ResourceId id, ShaderEntryPoint entry)
|
||||
ShaderReflection *ReplayProxy::GetShader(ResourceId pipeline, ResourceId shader,
|
||||
ShaderEntryPoint entry)
|
||||
{
|
||||
PROXY_FUNCTION(GetShader, id, entry);
|
||||
PROXY_FUNCTION(GetShader, pipeline, shader, entry);
|
||||
}
|
||||
|
||||
template <typename ParamSerialiser, typename ReturnSerialiser>
|
||||
@@ -1166,7 +1171,7 @@ std::string ReplayProxy::Proxied_DisassembleShader(ParamSerialiser ¶mser,
|
||||
|
||||
if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored)
|
||||
{
|
||||
refl = m_Remote->GetShader(m_Remote->GetLiveID(Shader), EntryPoint);
|
||||
refl = m_Remote->GetShader(pipeline, m_Remote->GetLiveID(Shader), EntryPoint);
|
||||
ret = m_Remote->DisassembleShader(pipeline, refl, target);
|
||||
}
|
||||
|
||||
@@ -1591,11 +1596,13 @@ void ReplayProxy::Proxied_SavePipelineState(ParamSerialiser ¶mser, ReturnSer
|
||||
|
||||
for(int i = 0; i < 6; i++)
|
||||
if(stages[i]->resourceId != ResourceId())
|
||||
stages[i]->reflection = GetShader(GetLiveID(stages[i]->resourceId), ShaderEntryPoint());
|
||||
stages[i]->reflection =
|
||||
GetShader(ResourceId(), GetLiveID(stages[i]->resourceId), ShaderEntryPoint());
|
||||
|
||||
if(m_D3D11PipelineState.inputAssembly.resourceId != ResourceId())
|
||||
m_D3D11PipelineState.inputAssembly.bytecode = GetShader(
|
||||
GetLiveID(m_D3D11PipelineState.inputAssembly.resourceId), ShaderEntryPoint());
|
||||
m_D3D11PipelineState.inputAssembly.bytecode =
|
||||
GetShader(ResourceId(), GetLiveID(m_D3D11PipelineState.inputAssembly.resourceId),
|
||||
ShaderEntryPoint());
|
||||
}
|
||||
else if(m_APIProps.pipelineType == GraphicsAPI::D3D12)
|
||||
{
|
||||
@@ -1605,9 +1612,12 @@ void ReplayProxy::Proxied_SavePipelineState(ParamSerialiser ¶mser, ReturnSer
|
||||
&m_D3D12PipelineState.pixelShader, &m_D3D12PipelineState.computeShader,
|
||||
};
|
||||
|
||||
ResourceId pipe = GetLiveID(m_D3D12PipelineState.pipelineResourceId);
|
||||
|
||||
for(int i = 0; i < 6; i++)
|
||||
if(stages[i]->resourceId != ResourceId())
|
||||
stages[i]->reflection = GetShader(GetLiveID(stages[i]->resourceId), ShaderEntryPoint());
|
||||
stages[i]->reflection =
|
||||
GetShader(pipe, GetLiveID(stages[i]->resourceId), ShaderEntryPoint());
|
||||
}
|
||||
else if(m_APIProps.pipelineType == GraphicsAPI::OpenGL)
|
||||
{
|
||||
@@ -1620,7 +1630,7 @@ void ReplayProxy::Proxied_SavePipelineState(ParamSerialiser ¶mser, ReturnSer
|
||||
for(int i = 0; i < 6; i++)
|
||||
if(stages[i]->shaderResourceId != ResourceId())
|
||||
stages[i]->reflection =
|
||||
GetShader(GetLiveID(stages[i]->shaderResourceId), ShaderEntryPoint());
|
||||
GetShader(ResourceId(), GetLiveID(stages[i]->shaderResourceId), ShaderEntryPoint());
|
||||
}
|
||||
else if(m_APIProps.pipelineType == GraphicsAPI::Vulkan)
|
||||
{
|
||||
@@ -1630,11 +1640,18 @@ void ReplayProxy::Proxied_SavePipelineState(ParamSerialiser ¶mser, ReturnSer
|
||||
&m_VulkanPipelineState.fragmentShader, &m_VulkanPipelineState.computeShader,
|
||||
};
|
||||
|
||||
ResourceId pipe = GetLiveID(m_VulkanPipelineState.graphics.pipelineResourceId);
|
||||
|
||||
for(int i = 0; i < 6; i++)
|
||||
{
|
||||
if(i == 5)
|
||||
pipe = GetLiveID(m_VulkanPipelineState.compute.pipelineResourceId);
|
||||
|
||||
if(stages[i]->resourceId != ResourceId())
|
||||
stages[i]->reflection =
|
||||
GetShader(GetLiveID(stages[i]->resourceId),
|
||||
GetShader(pipe, GetLiveID(stages[i]->resourceId),
|
||||
ShaderEntryPoint(stages[i]->entryPoint, stages[i]->stage));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2573,7 +2590,7 @@ bool ReplayProxy::Tick(int type)
|
||||
case eReplayProxy_GetBuffers: GetBuffers(); break;
|
||||
case eReplayProxy_GetBuffer: GetBuffer(ResourceId()); break;
|
||||
case eReplayProxy_GetShaderEntryPoints: GetShaderEntryPoints(ResourceId()); break;
|
||||
case eReplayProxy_GetShader: GetShader(ResourceId(), ShaderEntryPoint()); break;
|
||||
case eReplayProxy_GetShader: GetShader(ResourceId(), ResourceId(), ShaderEntryPoint()); break;
|
||||
case eReplayProxy_GetDebugMessages: GetDebugMessages(); break;
|
||||
case eReplayProxy_GetBufferData:
|
||||
{
|
||||
@@ -2606,7 +2623,7 @@ bool ReplayProxy::Tick(int type)
|
||||
{
|
||||
rdcarray<ShaderVariable> vars;
|
||||
bytebuf data;
|
||||
FillCBufferVariables(ResourceId(), "", 0, vars, data);
|
||||
FillCBufferVariables(ResourceId(), ResourceId(), "", 0, vars, data);
|
||||
break;
|
||||
}
|
||||
case eReplayProxy_InitPostVS: InitPostVSBuffers(0); break;
|
||||
|
||||
@@ -490,9 +490,9 @@ public:
|
||||
IMPLEMENT_FUNCTION_PROXIED(std::vector<CounterResult>, FetchCounters,
|
||||
const std::vector<GPUCounter> &counterID);
|
||||
|
||||
IMPLEMENT_FUNCTION_PROXIED(void, FillCBufferVariables, ResourceId shader, std::string entryPoint,
|
||||
uint32_t cbufSlot, rdcarray<ShaderVariable> &outvars,
|
||||
const bytebuf &data);
|
||||
IMPLEMENT_FUNCTION_PROXIED(void, FillCBufferVariables, ResourceId pipeline, ResourceId shader,
|
||||
std::string entryPoint, uint32_t cbufSlot,
|
||||
rdcarray<ShaderVariable> &outvars, const bytebuf &data);
|
||||
|
||||
IMPLEMENT_FUNCTION_PROXIED(void, GetBufferData, ResourceId buff, uint64_t offset, uint64_t len,
|
||||
bytebuf &retData);
|
||||
@@ -509,7 +509,7 @@ public:
|
||||
const std::vector<uint32_t> &passEvents);
|
||||
|
||||
IMPLEMENT_FUNCTION_PROXIED(rdcarray<ShaderEntryPoint>, GetShaderEntryPoints, ResourceId shader);
|
||||
IMPLEMENT_FUNCTION_PROXIED(ShaderReflection *, GetShader, ResourceId shader,
|
||||
IMPLEMENT_FUNCTION_PROXIED(ShaderReflection *, GetShader, ResourceId pipeline, ResourceId,
|
||||
ShaderEntryPoint entry);
|
||||
|
||||
IMPLEMENT_FUNCTION_PROXIED(std::vector<std::string>, GetDisassemblyTargets);
|
||||
@@ -638,17 +638,23 @@ private:
|
||||
struct ShaderReflKey
|
||||
{
|
||||
ShaderReflKey() {}
|
||||
ShaderReflKey(uint32_t eid, ResourceId i, ShaderEntryPoint e) : eventId(eid), id(i), entry(e) {}
|
||||
ShaderReflKey(uint32_t eid, ResourceId p, ResourceId s, ShaderEntryPoint e)
|
||||
: eventId(eid), pipeline(p), shader(s), entry(e)
|
||||
{
|
||||
}
|
||||
uint32_t eventId;
|
||||
ResourceId id;
|
||||
ResourceId pipeline, shader;
|
||||
ShaderEntryPoint entry;
|
||||
bool operator<(const ShaderReflKey &o) const
|
||||
{
|
||||
if(eventId != o.eventId)
|
||||
return eventId < o.eventId;
|
||||
|
||||
if(id != o.id)
|
||||
return id < o.id;
|
||||
if(pipeline != o.pipeline)
|
||||
return pipeline < o.pipeline;
|
||||
|
||||
if(shader != o.shader)
|
||||
return shader < o.shader;
|
||||
|
||||
return entry < o.entry;
|
||||
}
|
||||
|
||||
@@ -438,7 +438,8 @@ rdcarray<ShaderEntryPoint> D3D11Replay::GetShaderEntryPoints(ResourceId shader)
|
||||
return {{"main", ret.stage}};
|
||||
}
|
||||
|
||||
ShaderReflection *D3D11Replay::GetShader(ResourceId shader, ShaderEntryPoint entry)
|
||||
ShaderReflection *D3D11Replay::GetShader(ResourceId pipeline, ResourceId shader,
|
||||
ShaderEntryPoint entry)
|
||||
{
|
||||
auto it = WrappedShader::m_ShaderList.find(shader);
|
||||
|
||||
@@ -659,7 +660,7 @@ void D3D11Replay::SavePipelineState(uint32_t eventId)
|
||||
ResourceId layoutId = GetIDForResource(rs->IA.Layout);
|
||||
|
||||
ret.inputAssembly.resourceId = rm->GetOriginalID(layoutId);
|
||||
ret.inputAssembly.bytecode = GetShader(layoutId, ShaderEntryPoint());
|
||||
ret.inputAssembly.bytecode = GetShader(ResourceId(), layoutId, ShaderEntryPoint());
|
||||
|
||||
ret.inputAssembly.layouts.resize(vec.size());
|
||||
for(size_t i = 0; i < vec.size(); i++)
|
||||
@@ -2592,7 +2593,8 @@ void D3D11Replay::RenderHighlightBox(float w, float h, float scale)
|
||||
}
|
||||
}
|
||||
|
||||
void D3D11Replay::FillCBufferVariables(ResourceId shader, std::string entryPoint, uint32_t cbufSlot,
|
||||
void D3D11Replay::FillCBufferVariables(ResourceId pipeline, ResourceId shader,
|
||||
std::string entryPoint, uint32_t cbufSlot,
|
||||
rdcarray<ShaderVariable> &outvars, const bytebuf &data)
|
||||
{
|
||||
auto it = WrappedShader::m_ShaderList.find(shader);
|
||||
|
||||
@@ -119,7 +119,7 @@ public:
|
||||
std::vector<DebugMessage> GetDebugMessages();
|
||||
|
||||
rdcarray<ShaderEntryPoint> GetShaderEntryPoints(ResourceId shader);
|
||||
ShaderReflection *GetShader(ResourceId shader, ShaderEntryPoint entry);
|
||||
ShaderReflection *GetShader(ResourceId pipeline, ResourceId shader, ShaderEntryPoint entry);
|
||||
|
||||
std::vector<std::string> GetDisassemblyTargets();
|
||||
std::string DisassembleShader(ResourceId pipeline, const ShaderReflection *refl,
|
||||
@@ -217,8 +217,9 @@ public:
|
||||
|
||||
void RenderHighlightBox(float w, float h, float scale);
|
||||
|
||||
void FillCBufferVariables(ResourceId shader, std::string entryPoint, uint32_t cbufSlot,
|
||||
rdcarray<ShaderVariable> &outvars, const bytebuf &data);
|
||||
void FillCBufferVariables(ResourceId pipeline, ResourceId shader, std::string entryPoint,
|
||||
uint32_t cbufSlot, rdcarray<ShaderVariable> &outvars,
|
||||
const bytebuf &data);
|
||||
|
||||
std::vector<PixelModification> PixelHistory(std::vector<EventUsage> events, ResourceId target,
|
||||
uint32_t x, uint32_t y, uint32_t slice, uint32_t mip,
|
||||
|
||||
@@ -409,7 +409,8 @@ rdcarray<ShaderEntryPoint> D3D12Replay::GetShaderEntryPoints(ResourceId shader)
|
||||
return {{"main", ret.stage}};
|
||||
}
|
||||
|
||||
ShaderReflection *D3D12Replay::GetShader(ResourceId shader, ShaderEntryPoint entry)
|
||||
ShaderReflection *D3D12Replay::GetShader(ResourceId pipeline, ResourceId shader,
|
||||
ShaderEntryPoint entry)
|
||||
{
|
||||
WrappedID3D12Shader *sh =
|
||||
m_pDevice->GetResourceManager()->GetCurrentAs<WrappedID3D12Shader>(shader);
|
||||
@@ -2652,7 +2653,8 @@ void D3D12Replay::GetBufferData(ResourceId buff, uint64_t offset, uint64_t lengt
|
||||
GetDebugManager()->GetBufferData(buffer, offset, length, retData);
|
||||
}
|
||||
|
||||
void D3D12Replay::FillCBufferVariables(ResourceId shader, std::string entryPoint, uint32_t cbufSlot,
|
||||
void D3D12Replay::FillCBufferVariables(ResourceId pipeline, ResourceId shader,
|
||||
std::string entryPoint, uint32_t cbufSlot,
|
||||
rdcarray<ShaderVariable> &outvars, const bytebuf &data)
|
||||
{
|
||||
if(shader == ResourceId())
|
||||
|
||||
@@ -78,7 +78,7 @@ public:
|
||||
std::vector<DebugMessage> GetDebugMessages();
|
||||
|
||||
rdcarray<ShaderEntryPoint> GetShaderEntryPoints(ResourceId shader);
|
||||
ShaderReflection *GetShader(ResourceId shader, ShaderEntryPoint entry);
|
||||
ShaderReflection *GetShader(ResourceId pipeline, ResourceId shader, ShaderEntryPoint entry);
|
||||
|
||||
std::vector<std::string> GetDisassemblyTargets();
|
||||
std::string DisassembleShader(ResourceId pipeline, const ShaderReflection *refl,
|
||||
@@ -178,8 +178,9 @@ public:
|
||||
|
||||
void RenderHighlightBox(float w, float h, float scale);
|
||||
|
||||
void FillCBufferVariables(ResourceId shader, std::string entryPoint, uint32_t cbufSlot,
|
||||
rdcarray<ShaderVariable> &outvars, const bytebuf &data);
|
||||
void FillCBufferVariables(ResourceId pipeline, ResourceId shader, std::string entryPoint,
|
||||
uint32_t cbufSlot, rdcarray<ShaderVariable> &outvars,
|
||||
const bytebuf &data);
|
||||
|
||||
std::vector<PixelModification> PixelHistory(std::vector<EventUsage> events, ResourceId target,
|
||||
uint32_t x, uint32_t y, uint32_t slice, uint32_t mip,
|
||||
|
||||
@@ -123,7 +123,7 @@ bool GLReplay::CreateOverlayProgram(GLuint Program, GLuint Pipeline, GLuint frag
|
||||
}
|
||||
|
||||
if(i == 0)
|
||||
vsRefl = GetShader(pipeDetails.stageShaders[i], ShaderEntryPoint());
|
||||
vsRefl = GetShader(ResourceId(), pipeDetails.stageShaders[i], ShaderEntryPoint());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -151,7 +151,7 @@ bool GLReplay::CreateOverlayProgram(GLuint Program, GLuint Pipeline, GLuint frag
|
||||
HasGLSLShaders = true;
|
||||
|
||||
if(i == 0)
|
||||
vsRefl = GetShader(progDetails.stageShaders[0], ShaderEntryPoint());
|
||||
vsRefl = GetShader(ResourceId(), progDetails.stageShaders[0], ShaderEntryPoint());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,18 +125,18 @@ void GLReplay::InitPostVSBuffers(uint32_t eventId)
|
||||
{
|
||||
if(i == 0)
|
||||
{
|
||||
vsRefl = GetShader(pipeDetails.stageShaders[i], ShaderEntryPoint());
|
||||
vsRefl = GetShader(ResourceId(), pipeDetails.stageShaders[i], ShaderEntryPoint());
|
||||
glslVer = m_pDriver->m_Shaders[pipeDetails.stageShaders[0]].version;
|
||||
vsPatch = m_pDriver->m_Shaders[pipeDetails.stageShaders[0]].patchData;
|
||||
}
|
||||
else if(i == 2)
|
||||
{
|
||||
tesRefl = GetShader(pipeDetails.stageShaders[2], ShaderEntryPoint());
|
||||
tesRefl = GetShader(ResourceId(), pipeDetails.stageShaders[2], ShaderEntryPoint());
|
||||
tesPatch = m_pDriver->m_Shaders[pipeDetails.stageShaders[2]].patchData;
|
||||
}
|
||||
else if(i == 3)
|
||||
{
|
||||
gsRefl = GetShader(pipeDetails.stageShaders[3], ShaderEntryPoint());
|
||||
gsRefl = GetShader(ResourceId(), pipeDetails.stageShaders[3], ShaderEntryPoint());
|
||||
gsPatch = m_pDriver->m_Shaders[pipeDetails.stageShaders[3]].patchData;
|
||||
}
|
||||
|
||||
@@ -202,18 +202,18 @@ void GLReplay::InitPostVSBuffers(uint32_t eventId)
|
||||
{
|
||||
if(i == 0)
|
||||
{
|
||||
vsRefl = GetShader(progDetails.stageShaders[0], ShaderEntryPoint());
|
||||
vsRefl = GetShader(ResourceId(), progDetails.stageShaders[0], ShaderEntryPoint());
|
||||
glslVer = m_pDriver->m_Shaders[progDetails.stageShaders[0]].version;
|
||||
vsPatch = m_pDriver->m_Shaders[progDetails.stageShaders[0]].patchData;
|
||||
}
|
||||
else if(i == 2 && progDetails.stageShaders[2] != ResourceId())
|
||||
{
|
||||
tesRefl = GetShader(progDetails.stageShaders[2], ShaderEntryPoint());
|
||||
tesRefl = GetShader(ResourceId(), progDetails.stageShaders[2], ShaderEntryPoint());
|
||||
tesPatch = m_pDriver->m_Shaders[progDetails.stageShaders[2]].patchData;
|
||||
}
|
||||
else if(i == 3 && progDetails.stageShaders[3] != ResourceId())
|
||||
{
|
||||
gsRefl = GetShader(progDetails.stageShaders[3], ShaderEntryPoint());
|
||||
gsRefl = GetShader(ResourceId(), progDetails.stageShaders[3], ShaderEntryPoint());
|
||||
gsPatch = m_pDriver->m_Shaders[progDetails.stageShaders[3]].patchData;
|
||||
}
|
||||
|
||||
|
||||
@@ -726,7 +726,7 @@ rdcarray<ShaderEntryPoint> GLReplay::GetShaderEntryPoints(ResourceId shader)
|
||||
return {{shaderDetails.reflection.entryPoint, shaderDetails.reflection.stage}};
|
||||
}
|
||||
|
||||
ShaderReflection *GLReplay::GetShader(ResourceId shader, ShaderEntryPoint entry)
|
||||
ShaderReflection *GLReplay::GetShader(ResourceId pipeline, ResourceId shader, ShaderEntryPoint entry)
|
||||
{
|
||||
auto &shaderDetails = m_pDriver->m_Shaders[shader];
|
||||
|
||||
@@ -2150,8 +2150,9 @@ void GLReplay::OpenGLFillCBufferVariables(GLuint prog, bool bufferBacked, std::s
|
||||
}
|
||||
}
|
||||
|
||||
void GLReplay::FillCBufferVariables(ResourceId shader, std::string entryPoint, uint32_t cbufSlot,
|
||||
rdcarray<ShaderVariable> &outvars, const bytebuf &data)
|
||||
void GLReplay::FillCBufferVariables(ResourceId pipeline, ResourceId shader, std::string entryPoint,
|
||||
uint32_t cbufSlot, rdcarray<ShaderVariable> &outvars,
|
||||
const bytebuf &data)
|
||||
{
|
||||
WrappedOpenGL &drv = *m_pDriver;
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ public:
|
||||
TextureDescription GetTexture(ResourceId id);
|
||||
|
||||
rdcarray<ShaderEntryPoint> GetShaderEntryPoints(ResourceId shader);
|
||||
ShaderReflection *GetShader(ResourceId shader, ShaderEntryPoint entry);
|
||||
ShaderReflection *GetShader(ResourceId pipeline, ResourceId shader, ShaderEntryPoint entry);
|
||||
|
||||
std::vector<std::string> GetDisassemblyTargets();
|
||||
std::string DisassembleShader(ResourceId pipeline, const ShaderReflection *refl,
|
||||
@@ -194,8 +194,9 @@ public:
|
||||
|
||||
void RenderHighlightBox(float w, float h, float scale);
|
||||
|
||||
void FillCBufferVariables(ResourceId shader, std::string entryPoint, uint32_t cbufSlot,
|
||||
rdcarray<ShaderVariable> &outvars, const bytebuf &data);
|
||||
void FillCBufferVariables(ResourceId pipeline, ResourceId shader, std::string entryPoint,
|
||||
uint32_t cbufSlot, rdcarray<ShaderVariable> &outvars,
|
||||
const bytebuf &data);
|
||||
|
||||
std::vector<PixelModification> PixelHistory(std::vector<EventUsage> events, ResourceId target,
|
||||
uint32_t x, uint32_t y, uint32_t slice, uint32_t mip,
|
||||
|
||||
@@ -3526,7 +3526,7 @@ void MakeOnlineShaderReflection(ShaderStage stage, const std::string &source,
|
||||
return;
|
||||
}
|
||||
|
||||
refl = *driver->GetShader(id, ShaderEntryPoint("main", ShaderStage::Fragment));
|
||||
refl = *driver->GetShader(ResourceId(), id, ShaderEntryPoint("main", ShaderStage::Fragment));
|
||||
|
||||
// Note that we can't fill out ShaderBindpointMapping easily on the actual driver through the
|
||||
// replay interface
|
||||
|
||||
@@ -204,7 +204,8 @@ bool DescSetLayout::operator==(const DescSetLayout &other) const
|
||||
return true;
|
||||
}
|
||||
|
||||
void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info,
|
||||
void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan,
|
||||
VulkanCreationInfo &info, ResourceId id,
|
||||
const VkGraphicsPipelineCreateInfo *pCreateInfo)
|
||||
{
|
||||
flags = pCreateInfo->flags;
|
||||
@@ -223,23 +224,22 @@ void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan, Vulk
|
||||
// VkPipelineShaderStageCreateInfo
|
||||
for(uint32_t i = 0; i < pCreateInfo->stageCount; i++)
|
||||
{
|
||||
ResourceId id = GetResID(pCreateInfo->pStages[i].module);
|
||||
ResourceId shadid = GetResID(pCreateInfo->pStages[i].module);
|
||||
|
||||
// convert shader bit to shader index
|
||||
int stageIndex = StageIndex(pCreateInfo->pStages[i].stage);
|
||||
|
||||
Shader &shad = shaders[stageIndex];
|
||||
|
||||
shad.module = id;
|
||||
shad.module = shadid;
|
||||
shad.entryPoint = pCreateInfo->pStages[i].pName;
|
||||
|
||||
ShaderModule::Reflection &reflData = info.m_ShaderModule[id].m_Reflections[shad.entryPoint];
|
||||
|
||||
reflData.Init(resourceMan, id, info.m_ShaderModule[id].spirv, shad.entryPoint,
|
||||
pCreateInfo->pStages[i].stage);
|
||||
ShaderModuleReflectionKey key(shad.entryPoint, ResourceId());
|
||||
|
||||
if(pCreateInfo->pStages[i].pSpecializationInfo)
|
||||
{
|
||||
key = ShaderModuleReflectionKey(shad.entryPoint, id);
|
||||
|
||||
const byte *data = (const byte *)pCreateInfo->pStages[i].pSpecializationInfo->pData;
|
||||
|
||||
const VkSpecializationMapEntry *maps = pCreateInfo->pStages[i].pSpecializationInfo->pMapEntries;
|
||||
@@ -253,6 +253,11 @@ void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan, Vulk
|
||||
}
|
||||
}
|
||||
|
||||
ShaderModuleReflection &reflData = info.m_ShaderModule[shadid].m_Reflections[key];
|
||||
|
||||
reflData.Init(resourceMan, shadid, info.m_ShaderModule[shadid].spirv, shad.entryPoint,
|
||||
pCreateInfo->pStages[i].stage, shad.specialization);
|
||||
|
||||
shad.refl = &reflData.refl;
|
||||
shad.mapping = &reflData.mapping;
|
||||
shad.patchData = &reflData.patchData;
|
||||
@@ -544,7 +549,7 @@ void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan, Vulk
|
||||
}
|
||||
|
||||
void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info,
|
||||
const VkComputePipelineCreateInfo *pCreateInfo)
|
||||
ResourceId id, const VkComputePipelineCreateInfo *pCreateInfo)
|
||||
{
|
||||
flags = pCreateInfo->flags;
|
||||
|
||||
@@ -554,19 +559,18 @@ void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan, Vulk
|
||||
|
||||
// VkPipelineShaderStageCreateInfo
|
||||
{
|
||||
ResourceId id = GetResID(pCreateInfo->stage.module);
|
||||
ResourceId shadid = GetResID(pCreateInfo->stage.module);
|
||||
Shader &shad = shaders[5]; // 5 is the compute shader's index (VS, TCS, TES, GS, FS, CS)
|
||||
|
||||
shad.module = id;
|
||||
shad.module = shadid;
|
||||
shad.entryPoint = pCreateInfo->stage.pName;
|
||||
|
||||
ShaderModule::Reflection &reflData = info.m_ShaderModule[id].m_Reflections[shad.entryPoint];
|
||||
|
||||
reflData.Init(resourceMan, id, info.m_ShaderModule[id].spirv, shad.entryPoint,
|
||||
pCreateInfo->stage.stage);
|
||||
ShaderModuleReflectionKey key(shad.entryPoint, ResourceId());
|
||||
|
||||
if(pCreateInfo->stage.pSpecializationInfo)
|
||||
{
|
||||
key = ShaderModuleReflectionKey(shad.entryPoint, id);
|
||||
|
||||
const byte *data = (const byte *)pCreateInfo->stage.pSpecializationInfo->pData;
|
||||
|
||||
const VkSpecializationMapEntry *maps = pCreateInfo->stage.pSpecializationInfo->pMapEntries;
|
||||
@@ -580,6 +584,11 @@ void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan, Vulk
|
||||
}
|
||||
}
|
||||
|
||||
ShaderModuleReflection &reflData = info.m_ShaderModule[shadid].m_Reflections[key];
|
||||
|
||||
reflData.Init(resourceMan, shadid, info.m_ShaderModule[shadid].spirv, shad.entryPoint,
|
||||
pCreateInfo->stage.stage, shad.specialization);
|
||||
|
||||
shad.refl = &reflData.refl;
|
||||
shad.mapping = &reflData.mapping;
|
||||
shad.patchData = &reflData.patchData;
|
||||
@@ -1044,18 +1053,19 @@ void VulkanCreationInfo::ShaderModule::Init(VulkanResourceManager *resourceMan,
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanCreationInfo::ShaderModule::Reflection::Init(VulkanResourceManager *resourceMan,
|
||||
ResourceId id, const rdcspv::Reflector &spv,
|
||||
const std::string &entry,
|
||||
VkShaderStageFlagBits stage)
|
||||
void VulkanCreationInfo::ShaderModuleReflection::Init(VulkanResourceManager *resourceMan,
|
||||
ResourceId id, const rdcspv::Reflector &spv,
|
||||
const std::string &entry,
|
||||
VkShaderStageFlagBits stage,
|
||||
const std::vector<SpecConstant> &specInfo)
|
||||
{
|
||||
if(entryPoint.empty())
|
||||
{
|
||||
entryPoint = entry;
|
||||
stageIndex = StageIndex(stage);
|
||||
|
||||
spv.MakeReflection(GraphicsAPI::Vulkan, ShaderStage(stageIndex), entryPoint, {}, refl, mapping,
|
||||
patchData);
|
||||
spv.MakeReflection(GraphicsAPI::Vulkan, ShaderStage(stageIndex), entryPoint, specInfo, refl,
|
||||
mapping, patchData);
|
||||
|
||||
refl.resourceId = resourceMan->GetOriginalID(id);
|
||||
}
|
||||
|
||||
@@ -135,11 +135,42 @@ struct DescUpdateTemplate
|
||||
|
||||
struct VulkanCreationInfo
|
||||
{
|
||||
struct ShaderModuleReflectionKey
|
||||
{
|
||||
ShaderModuleReflectionKey(const rdcstr &e, ResourceId p) : entryPoint(e), specialisingPipe(p) {}
|
||||
bool operator<(const ShaderModuleReflectionKey &o) const
|
||||
{
|
||||
if(entryPoint != o.entryPoint)
|
||||
return entryPoint < o.entryPoint;
|
||||
|
||||
return specialisingPipe < o.specialisingPipe;
|
||||
}
|
||||
|
||||
// name of the entry point
|
||||
rdcstr entryPoint;
|
||||
// ID of the pipeline ONLY if it contains specialisation constant data
|
||||
ResourceId specialisingPipe;
|
||||
};
|
||||
|
||||
struct ShaderModuleReflection
|
||||
{
|
||||
uint32_t stageIndex;
|
||||
std::string entryPoint;
|
||||
std::string disassembly;
|
||||
ShaderReflection refl;
|
||||
ShaderBindpointMapping mapping;
|
||||
SPIRVPatchData patchData;
|
||||
|
||||
void Init(VulkanResourceManager *resourceMan, ResourceId id, const rdcspv::Reflector &spv,
|
||||
const std::string &entry, VkShaderStageFlagBits stage,
|
||||
const std::vector<SpecConstant> &specInfo);
|
||||
};
|
||||
|
||||
struct Pipeline
|
||||
{
|
||||
void Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info,
|
||||
void Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, ResourceId id,
|
||||
const VkGraphicsPipelineCreateInfo *pCreateInfo);
|
||||
void Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info,
|
||||
void Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, ResourceId id,
|
||||
const VkComputePipelineCreateInfo *pCreateInfo);
|
||||
|
||||
ResourceId layout;
|
||||
@@ -469,23 +500,22 @@ struct VulkanCreationInfo
|
||||
void Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info,
|
||||
const VkShaderModuleCreateInfo *pCreateInfo);
|
||||
|
||||
ShaderModuleReflection &GetReflection(const rdcstr &entry, ResourceId pipe)
|
||||
{
|
||||
// look for one from this pipeline specifically, if it was specialised
|
||||
auto it = m_Reflections.find({entry, pipe});
|
||||
if(it != m_Reflections.end())
|
||||
return it->second;
|
||||
|
||||
// if not, just return the non-specialised version
|
||||
return m_Reflections[{entry, ResourceId()}];
|
||||
}
|
||||
|
||||
rdcspv::Reflector spirv;
|
||||
|
||||
std::string unstrippedPath;
|
||||
|
||||
struct Reflection
|
||||
{
|
||||
uint32_t stageIndex;
|
||||
std::string entryPoint;
|
||||
std::string disassembly;
|
||||
ShaderReflection refl;
|
||||
ShaderBindpointMapping mapping;
|
||||
SPIRVPatchData patchData;
|
||||
|
||||
void Init(VulkanResourceManager *resourceMan, ResourceId id, const rdcspv::Reflector &spv,
|
||||
const std::string &entry, VkShaderStageFlagBits stage);
|
||||
};
|
||||
std::map<std::string, Reflection> m_Reflections;
|
||||
std::map<ShaderModuleReflectionKey, ShaderModuleReflection> m_Reflections;
|
||||
};
|
||||
std::map<ResourceId, ShaderModule> m_ShaderModule;
|
||||
|
||||
|
||||
@@ -330,7 +330,8 @@ rdcarray<ShaderEntryPoint> VulkanReplay::GetShaderEntryPoints(ResourceId shader)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ShaderReflection *VulkanReplay::GetShader(ResourceId shader, ShaderEntryPoint entry)
|
||||
ShaderReflection *VulkanReplay::GetShader(ResourceId pipeline, ResourceId shader,
|
||||
ShaderEntryPoint entry)
|
||||
{
|
||||
auto shad = m_pDriver->m_CreationInfo.m_ShaderModule.find(shader);
|
||||
|
||||
@@ -340,11 +341,13 @@ ShaderReflection *VulkanReplay::GetShader(ResourceId shader, ShaderEntryPoint en
|
||||
return NULL;
|
||||
}
|
||||
|
||||
shad->second.m_Reflections[entry.name].Init(GetResourceManager(), shader, shad->second.spirv,
|
||||
entry.name,
|
||||
VkShaderStageFlagBits(1 << uint32_t(entry.stage)));
|
||||
// if this shader was never used in a pipeline the reflection won't be prepared. Do that now -
|
||||
// this will be ignored if it was already prepared.
|
||||
shad->second.GetReflection(entry.name, pipeline)
|
||||
.Init(GetResourceManager(), shader, shad->second.spirv, entry.name,
|
||||
VkShaderStageFlagBits(1 << uint32_t(entry.stage)), {});
|
||||
|
||||
return &shad->second.m_Reflections[entry.name].refl;
|
||||
return &shad->second.GetReflection(entry.name, pipeline).refl;
|
||||
}
|
||||
|
||||
std::vector<std::string> VulkanReplay::GetDisassemblyTargets()
|
||||
@@ -450,7 +453,7 @@ std::string VulkanReplay::DisassembleShader(ResourceId pipeline, const ShaderRef
|
||||
|
||||
if(target == SPIRVDisassemblyTarget || target.empty())
|
||||
{
|
||||
std::string &disasm = it->second.m_Reflections[refl->entryPoint.c_str()].disassembly;
|
||||
std::string &disasm = it->second.GetReflection(refl->entryPoint, pipeline).disassembly;
|
||||
|
||||
if(disasm.empty())
|
||||
disasm = it->second.spirv.Disassemble(refl->entryPoint.c_str());
|
||||
@@ -472,7 +475,7 @@ std::string VulkanReplay::DisassembleShader(ResourceId pipeline, const ShaderRef
|
||||
VkPipeline pipe = m_pDriver->GetResourceManager()->GetLiveHandle<VkPipeline>(pipeline);
|
||||
|
||||
VkShaderStageFlagBits stageBit =
|
||||
VkShaderStageFlagBits(1 << it->second.m_Reflections[refl->entryPoint.c_str()].stageIndex);
|
||||
VkShaderStageFlagBits(1 << it->second.GetReflection(refl->entryPoint, pipeline).stageIndex);
|
||||
|
||||
size_t size;
|
||||
vt->GetShaderInfoAMD(Unwrap(dev), Unwrap(pipe), stageBit, VK_SHADER_INFO_TYPE_DISASSEMBLY_AMD,
|
||||
@@ -498,7 +501,7 @@ std::string VulkanReplay::DisassembleShader(ResourceId pipeline, const ShaderRef
|
||||
CachePipelineExecutables(pipeline);
|
||||
|
||||
VkShaderStageFlagBits stageBit =
|
||||
VkShaderStageFlagBits(1 << it->second.m_Reflections[refl->entryPoint.c_str()].stageIndex);
|
||||
VkShaderStageFlagBits(1 << it->second.GetReflection(refl->entryPoint, pipeline).stageIndex);
|
||||
|
||||
const rdcarray<PipelineExecutables> &executables = m_PipelineExecutables[pipeline];
|
||||
|
||||
@@ -1956,13 +1959,10 @@ void VulkanReplay::SavePipelineState(uint32_t eventId)
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanReplay::FillCBufferVariables(ResourceId shader, std::string entryPoint, uint32_t cbufSlot,
|
||||
void VulkanReplay::FillCBufferVariables(ResourceId pipeline, ResourceId shader,
|
||||
std::string entryPoint, uint32_t cbufSlot,
|
||||
rdcarray<ShaderVariable> &outvars, const bytebuf &data)
|
||||
{
|
||||
// Correct SPIR-V will ultimately need to set explicit layout information for each type.
|
||||
// For now, just assume D3D11 packing (float4 alignment on float4s, float3s, matrices, arrays and
|
||||
// structures)
|
||||
|
||||
auto it = m_pDriver->m_CreationInfo.m_ShaderModule.find(shader);
|
||||
|
||||
if(it == m_pDriver->m_CreationInfo.m_ShaderModule.end())
|
||||
@@ -1971,8 +1971,8 @@ void VulkanReplay::FillCBufferVariables(ResourceId shader, std::string entryPoin
|
||||
return;
|
||||
}
|
||||
|
||||
ShaderReflection &refl = it->second.m_Reflections[entryPoint].refl;
|
||||
ShaderBindpointMapping &mapping = it->second.m_Reflections[entryPoint].mapping;
|
||||
ShaderReflection &refl = it->second.GetReflection(entryPoint, pipeline).refl;
|
||||
ShaderBindpointMapping &mapping = it->second.GetReflection(entryPoint, pipeline).mapping;
|
||||
|
||||
if(cbufSlot >= (uint32_t)refl.constantBlocks.count())
|
||||
{
|
||||
@@ -1991,21 +1991,14 @@ void VulkanReplay::FillCBufferVariables(ResourceId shader, std::string entryPoin
|
||||
// specialised path to display specialization constants
|
||||
if(mapping.constantBlocks[c.bindPoint].bindset == SpecializationConstantBindSet)
|
||||
{
|
||||
// TODO we shouldn't be looking up the pipeline here, this query should work regardless.
|
||||
ResourceId pipeline = refl.stage == ShaderStage::Compute
|
||||
? m_pDriver->m_RenderState.compute.pipeline
|
||||
: m_pDriver->m_RenderState.graphics.pipeline;
|
||||
if(pipeline != ResourceId())
|
||||
auto pipeIt = m_pDriver->m_CreationInfo.m_Pipeline.find(pipeline);
|
||||
|
||||
if(pipeIt != m_pDriver->m_CreationInfo.m_Pipeline.end())
|
||||
{
|
||||
auto pipeIt = m_pDriver->m_CreationInfo.m_Pipeline.find(pipeline);
|
||||
auto specInfo =
|
||||
pipeIt->second.shaders[it->second.GetReflection(entryPoint, pipeline).stageIndex].specialization;
|
||||
|
||||
if(pipeIt != m_pDriver->m_CreationInfo.m_Pipeline.end())
|
||||
{
|
||||
auto specInfo =
|
||||
pipeIt->second.shaders[it->second.m_Reflections[entryPoint].stageIndex].specialization;
|
||||
|
||||
FillSpecConstantVariables(c.variables, outvars, specInfo);
|
||||
}
|
||||
FillSpecConstantVariables(c.variables, outvars, specInfo);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -243,7 +243,7 @@ public:
|
||||
TextureDescription GetTexture(ResourceId id);
|
||||
|
||||
rdcarray<ShaderEntryPoint> GetShaderEntryPoints(ResourceId shader);
|
||||
ShaderReflection *GetShader(ResourceId shader, ShaderEntryPoint entry);
|
||||
ShaderReflection *GetShader(ResourceId pipeline, ResourceId shader, ShaderEntryPoint entry);
|
||||
|
||||
std::vector<std::string> GetDisassemblyTargets();
|
||||
std::string DisassembleShader(ResourceId pipeline, const ShaderReflection *refl,
|
||||
@@ -334,8 +334,9 @@ public:
|
||||
|
||||
void RenderHighlightBox(float w, float h, float scale);
|
||||
|
||||
void FillCBufferVariables(ResourceId shader, std::string entryPoint, uint32_t cbufSlot,
|
||||
rdcarray<ShaderVariable> &outvars, const bytebuf &data);
|
||||
void FillCBufferVariables(ResourceId pipeline, ResourceId shader, std::string entryPoint,
|
||||
uint32_t cbufSlot, rdcarray<ShaderVariable> &outvars,
|
||||
const bytebuf &data);
|
||||
|
||||
std::vector<PixelModification> PixelHistory(std::vector<EventUsage> events, ResourceId target,
|
||||
uint32_t x, uint32_t y, uint32_t slice, uint32_t mip,
|
||||
|
||||
@@ -459,7 +459,7 @@ bool WrappedVulkan::Serialise_vkCreateGraphicsPipelines(
|
||||
|
||||
VulkanCreationInfo::Pipeline &pipeInfo = m_CreationInfo.m_Pipeline[live];
|
||||
|
||||
pipeInfo.Init(GetResourceManager(), m_CreationInfo, &CreateInfo);
|
||||
pipeInfo.Init(GetResourceManager(), m_CreationInfo, live, &CreateInfo);
|
||||
|
||||
ResourceId renderPassID = GetResID(CreateInfo.renderPass);
|
||||
|
||||
@@ -588,7 +588,8 @@ VkResult WrappedVulkan::vkCreateGraphicsPipelines(VkDevice device, VkPipelineCac
|
||||
{
|
||||
GetResourceManager()->AddLiveResource(id, pPipelines[i]);
|
||||
|
||||
m_CreationInfo.m_Pipeline[id].Init(GetResourceManager(), m_CreationInfo, &pCreateInfos[i]);
|
||||
m_CreationInfo.m_Pipeline[id].Init(GetResourceManager(), m_CreationInfo, id,
|
||||
&pCreateInfos[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -657,7 +658,7 @@ bool WrappedVulkan::Serialise_vkCreateComputePipelines(SerialiserType &ser, VkDe
|
||||
live = GetResourceManager()->WrapResource(Unwrap(device), pipe);
|
||||
GetResourceManager()->AddLiveResource(Pipeline, pipe);
|
||||
|
||||
m_CreationInfo.m_Pipeline[live].Init(GetResourceManager(), m_CreationInfo, &CreateInfo);
|
||||
m_CreationInfo.m_Pipeline[live].Init(GetResourceManager(), m_CreationInfo, live, &CreateInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -758,7 +759,8 @@ VkResult WrappedVulkan::vkCreateComputePipelines(VkDevice device, VkPipelineCach
|
||||
{
|
||||
GetResourceManager()->AddLiveResource(id, pPipelines[i]);
|
||||
|
||||
m_CreationInfo.m_Pipeline[id].Init(GetResourceManager(), m_CreationInfo, &pCreateInfos[i]);
|
||||
m_CreationInfo.m_Pipeline[id].Init(GetResourceManager(), m_CreationInfo, id,
|
||||
&pCreateInfos[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -593,11 +593,12 @@ rdcarray<ShaderEntryPoint> ReplayController::GetShaderEntryPoints(ResourceId sha
|
||||
return m_pDevice->GetShaderEntryPoints(m_pDevice->GetLiveID(shader));
|
||||
}
|
||||
|
||||
ShaderReflection *ReplayController::GetShader(ResourceId shader, ShaderEntryPoint entry)
|
||||
ShaderReflection *ReplayController::GetShader(ResourceId pipeline, ResourceId shader,
|
||||
ShaderEntryPoint entry)
|
||||
{
|
||||
CHECK_REPLAY_THREAD();
|
||||
|
||||
return m_pDevice->GetShader(m_pDevice->GetLiveID(shader), entry);
|
||||
return m_pDevice->GetShader(m_pDevice->GetLiveID(pipeline), m_pDevice->GetLiveID(shader), entry);
|
||||
}
|
||||
|
||||
rdcarray<EventUsage> ReplayController::GetUsage(ResourceId id)
|
||||
@@ -1704,7 +1705,8 @@ void ReplayController::FreeTrace(ShaderDebugTrace *trace)
|
||||
}
|
||||
|
||||
rdcarray<ShaderVariable> ReplayController::GetCBufferVariableContents(
|
||||
ResourceId shader, const char *entryPoint, uint32_t cbufslot, ResourceId buffer, uint64_t offs)
|
||||
ResourceId pipeline, ResourceId shader, const char *entryPoint, uint32_t cbufslot,
|
||||
ResourceId buffer, uint64_t offs)
|
||||
{
|
||||
CHECK_REPLAY_THREAD();
|
||||
|
||||
@@ -1718,10 +1720,11 @@ rdcarray<ShaderVariable> ReplayController::GetCBufferVariableContents(
|
||||
|
||||
rdcarray<ShaderVariable> v;
|
||||
|
||||
pipeline = m_pDevice->GetLiveID(pipeline);
|
||||
shader = m_pDevice->GetLiveID(shader);
|
||||
|
||||
if(shader != ResourceId())
|
||||
m_pDevice->FillCBufferVariables(shader, entryPoint, cbufslot, v, data);
|
||||
m_pDevice->FillCBufferVariables(pipeline, shader, entryPoint, cbufslot, v, data);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
@@ -182,7 +182,7 @@ public:
|
||||
rdcarray<DebugMessage> GetDebugMessages();
|
||||
|
||||
rdcarray<ShaderEntryPoint> GetShaderEntryPoints(ResourceId shader);
|
||||
ShaderReflection *GetShader(ResourceId shader, ShaderEntryPoint entry);
|
||||
ShaderReflection *GetShader(ResourceId pipeline, ResourceId shader, ShaderEntryPoint entry);
|
||||
|
||||
rdcarray<PixelModification> PixelHistory(ResourceId target, uint32_t x, uint32_t y, uint32_t slice,
|
||||
uint32_t mip, uint32_t sampleIdx, CompType typeHint);
|
||||
@@ -201,9 +201,9 @@ public:
|
||||
|
||||
bool SaveTexture(const TextureSave &saveData, const char *path);
|
||||
|
||||
rdcarray<ShaderVariable> GetCBufferVariableContents(ResourceId shader, const char *entryPoint,
|
||||
uint32_t cbufslot, ResourceId buffer,
|
||||
uint64_t offs);
|
||||
rdcarray<ShaderVariable> GetCBufferVariableContents(ResourceId pipeline, ResourceId shader,
|
||||
const char *entryPoint, uint32_t cbufslot,
|
||||
ResourceId buffer, uint64_t offs);
|
||||
|
||||
rdcarray<WindowingSystem> GetSupportedWindowSystems();
|
||||
|
||||
|
||||
@@ -103,7 +103,8 @@ public:
|
||||
virtual std::vector<DebugMessage> GetDebugMessages() = 0;
|
||||
|
||||
virtual rdcarray<ShaderEntryPoint> GetShaderEntryPoints(ResourceId shader) = 0;
|
||||
virtual ShaderReflection *GetShader(ResourceId shader, ShaderEntryPoint entry) = 0;
|
||||
virtual ShaderReflection *GetShader(ResourceId pipeline, ResourceId shader,
|
||||
ShaderEntryPoint entry) = 0;
|
||||
|
||||
virtual std::vector<std::string> GetDisassemblyTargets() = 0;
|
||||
virtual std::string DisassembleShader(ResourceId pipeline, const ShaderReflection *refl,
|
||||
@@ -149,8 +150,9 @@ public:
|
||||
virtual CounterDescription DescribeCounter(GPUCounter counterID) = 0;
|
||||
virtual std::vector<CounterResult> FetchCounters(const std::vector<GPUCounter> &counterID) = 0;
|
||||
|
||||
virtual void FillCBufferVariables(ResourceId shader, std::string entryPoint, uint32_t cbufSlot,
|
||||
rdcarray<ShaderVariable> &outvars, const bytebuf &data) = 0;
|
||||
virtual void FillCBufferVariables(ResourceId pipeline, ResourceId shader, std::string entryPoint,
|
||||
uint32_t cbufSlot, rdcarray<ShaderVariable> &outvars,
|
||||
const bytebuf &data) = 0;
|
||||
|
||||
virtual std::vector<PixelModification> PixelHistory(std::vector<EventUsage> events,
|
||||
ResourceId target, uint32_t x, uint32_t y,
|
||||
|
||||
@@ -23,6 +23,7 @@ set(VULKAN_SRC
|
||||
vk/vk_sample_locations.cpp
|
||||
vk/vk_secondary_cmdbuf.cpp
|
||||
vk/vk_simple_triangle.cpp
|
||||
vk/vk_spec_constants.cpp
|
||||
vk/vk_structured_buffer_nested.cpp
|
||||
vk/vk_vertex_attr_zoo.cpp
|
||||
vk/vk_video_textures.cpp
|
||||
|
||||
@@ -213,6 +213,7 @@
|
||||
<ClCompile Include="vk\vk_int8_ibuffer.cpp" />
|
||||
<ClCompile Include="vk\vk_line_raster.cpp" />
|
||||
<ClCompile Include="vk\vk_multi_thread_windows.cpp" />
|
||||
<ClCompile Include="vk\vk_spec_constants.cpp" />
|
||||
<ClCompile Include="vk\vk_vertex_attr_zoo.cpp" />
|
||||
<ClCompile Include="vk\vk_buffer_address.cpp" />
|
||||
<ClCompile Include="vk\vk_cbuffer_zoo.cpp" />
|
||||
|
||||
@@ -318,6 +318,9 @@
|
||||
<ClCompile Include="vk\vk_line_raster.cpp">
|
||||
<Filter>Vulkan\demos</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="vk\vk_spec_constants.cpp">
|
||||
<Filter>Vulkan\demos</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="D3D11">
|
||||
|
||||
@@ -0,0 +1,188 @@
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2018-2019 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 "vk_test.h"
|
||||
|
||||
TEST(VK_Spec_Constants, VulkanGraphicsTest)
|
||||
{
|
||||
static constexpr const char *Description =
|
||||
"Tests using the same shader multiple times with specialisation constants";
|
||||
|
||||
const std::string vertex = R"EOSHADER(
|
||||
#version 420 core
|
||||
|
||||
layout(location = 0) in vec3 Position;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(Position.xyz*vec3(1,-1,1), 1);
|
||||
}
|
||||
|
||||
)EOSHADER";
|
||||
|
||||
const std::string pixel = R"EOSHADER(
|
||||
#version 420 core
|
||||
|
||||
layout(location = 0, index = 0) out vec4 Color;
|
||||
|
||||
layout(constant_id = 0) const int numcols = 0;
|
||||
|
||||
layout(set = 0, binding = 0, std140) uniform constsbuf
|
||||
{
|
||||
vec4 col[numcols+1];
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
Color = vec4(0,0,0,1);
|
||||
for(int i=0; i < numcols; i++)
|
||||
Color += col[i];
|
||||
}
|
||||
|
||||
)EOSHADER";
|
||||
|
||||
int main()
|
||||
{
|
||||
// initialise, create window, create context, etc
|
||||
if(!Init())
|
||||
return 3;
|
||||
|
||||
VkDescriptorSetLayout setlayout = createDescriptorSetLayout(vkh::DescriptorSetLayoutCreateInfo({
|
||||
{0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
||||
}));
|
||||
|
||||
VkPipelineLayout layout = createPipelineLayout(vkh::PipelineLayoutCreateInfo({setlayout}));
|
||||
|
||||
vkh::GraphicsPipelineCreateInfo pipeCreateInfo;
|
||||
|
||||
pipeCreateInfo.layout = layout;
|
||||
pipeCreateInfo.renderPass = mainWindow->rp;
|
||||
|
||||
pipeCreateInfo.vertexInputState.vertexBindingDescriptions = {vkh::vertexBind(0, DefaultA2V)};
|
||||
pipeCreateInfo.vertexInputState.vertexAttributeDescriptions = {
|
||||
vkh::vertexAttr(0, 0, DefaultA2V, pos),
|
||||
};
|
||||
|
||||
pipeCreateInfo.stages = {
|
||||
CompileShaderModule(vertex, ShaderLang::glsl, ShaderStage::vert, "main"),
|
||||
CompileShaderModule(pixel, ShaderLang::glsl, ShaderStage::frag, "main"),
|
||||
};
|
||||
|
||||
VkSpecializationMapEntry specmap[1] = {
|
||||
{0, 0, sizeof(uint32_t)},
|
||||
};
|
||||
|
||||
uint32_t specval = 0;
|
||||
|
||||
VkSpecializationInfo spec = {};
|
||||
spec.mapEntryCount = 1;
|
||||
spec.pMapEntries = specmap;
|
||||
spec.dataSize = sizeof(specval);
|
||||
spec.pData = &specval;
|
||||
|
||||
pipeCreateInfo.stages[1].pSpecializationInfo = &spec;
|
||||
|
||||
VkPipeline pipe[4] = {};
|
||||
for(size_t i = 0; i < ARRAY_COUNT(pipe); i++)
|
||||
{
|
||||
specval = (uint32_t)i;
|
||||
pipe[i] = createGraphicsPipeline(pipeCreateInfo);
|
||||
}
|
||||
|
||||
Vec4f cbufferdata[4] = {
|
||||
Vec4f(1.0f, 0.0f, 0.0f, 0.0f), Vec4f(0.0, 1.0f, 0.0f, 0.0f), Vec4f(0.0, 0.0f, 1.0f, 0.0f),
|
||||
};
|
||||
|
||||
AllocatedBuffer cb(
|
||||
allocator, vkh::BufferCreateInfo(sizeof(cbufferdata), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT |
|
||||
VK_BUFFER_USAGE_TRANSFER_DST_BIT),
|
||||
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_CPU_TO_GPU}));
|
||||
|
||||
cb.upload(cbufferdata);
|
||||
|
||||
VkDescriptorSet descset = allocateDescriptorSet(setlayout);
|
||||
|
||||
vkh::updateDescriptorSets(
|
||||
device, {
|
||||
vkh::WriteDescriptorSet(descset, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||
{vkh::DescriptorBufferInfo(cb.buffer)}),
|
||||
});
|
||||
|
||||
AllocatedBuffer vb(
|
||||
allocator, vkh::BufferCreateInfo(sizeof(DefaultTri), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT |
|
||||
VK_BUFFER_USAGE_TRANSFER_DST_BIT),
|
||||
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_CPU_TO_GPU}));
|
||||
|
||||
vb.upload(DefaultTri);
|
||||
|
||||
while(Running())
|
||||
{
|
||||
VkCommandBuffer cmd = GetCommandBuffer();
|
||||
|
||||
vkBeginCommandBuffer(cmd, vkh::CommandBufferBeginInfo());
|
||||
|
||||
VkImage swapimg =
|
||||
StartUsingBackbuffer(cmd, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
|
||||
|
||||
vkCmdClearColorImage(cmd, swapimg, VK_IMAGE_LAYOUT_GENERAL,
|
||||
vkh::ClearColorValue(0.4f, 0.5f, 0.6f, 1.0f), 1,
|
||||
vkh::ImageSubresourceRange());
|
||||
|
||||
vkCmdBeginRenderPass(
|
||||
cmd, vkh::RenderPassBeginInfo(mainWindow->rp, mainWindow->GetFB(), mainWindow->scissor),
|
||||
VK_SUBPASS_CONTENTS_INLINE);
|
||||
|
||||
VkViewport v = mainWindow->viewport;
|
||||
v.width /= ARRAY_COUNT(pipe);
|
||||
|
||||
vkCmdSetScissor(cmd, 0, 1, &mainWindow->scissor);
|
||||
vkh::cmdBindVertexBuffers(cmd, 0, {vb.buffer}, {0});
|
||||
|
||||
for(size_t i = 0; i < ARRAY_COUNT(pipe); i++)
|
||||
{
|
||||
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe[i]);
|
||||
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, 1, &descset, 0,
|
||||
NULL);
|
||||
vkCmdSetViewport(cmd, 0, 1, &v);
|
||||
vkCmdDraw(cmd, 3, 1, 0, 0);
|
||||
|
||||
v.x += v.width;
|
||||
}
|
||||
|
||||
vkCmdEndRenderPass(cmd);
|
||||
|
||||
FinishUsingBackbuffer(cmd, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
|
||||
|
||||
vkEndCommandBuffer(cmd);
|
||||
|
||||
Submit(0, 1, {cmd});
|
||||
|
||||
Present();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
REGISTER_TEST();
|
||||
@@ -23,7 +23,8 @@ class D3D11_CBuffer_Zoo(rdtest.TestCase):
|
||||
cbuf: rd.BoundCBuffer = pipe.GetConstantBuffer(stage, 0, 0)
|
||||
|
||||
var_check = rdtest.ConstantBufferChecker(
|
||||
self.controller.GetCBufferVariableContents(pipe.GetShader(stage),
|
||||
self.controller.GetCBufferVariableContents(pipe.GetGraphicsPipelineObject(),
|
||||
pipe.GetShader(stage),
|
||||
pipe.GetShaderEntryPoint(stage), 0,
|
||||
cbuf.resourceId, cbuf.byteOffset))
|
||||
|
||||
|
||||
@@ -23,7 +23,8 @@ class D3D12_CBuffer_Zoo(rdtest.TestCase):
|
||||
cbuf: rd.BoundCBuffer = pipe.GetConstantBuffer(stage, 0, 0)
|
||||
|
||||
var_check = rdtest.ConstantBufferChecker(
|
||||
self.controller.GetCBufferVariableContents(pipe.GetShader(stage),
|
||||
self.controller.GetCBufferVariableContents(pipe.GetGraphicsPipelineObject(),
|
||||
pipe.GetShader(stage),
|
||||
pipe.GetShaderEntryPoint(stage), 0,
|
||||
cbuf.resourceId, cbuf.byteOffset))
|
||||
|
||||
@@ -328,7 +329,8 @@ class D3D12_CBuffer_Zoo(rdtest.TestCase):
|
||||
cbuf: rd.BoundCBuffer = pipe.GetConstantBuffer(stage, 1, 0)
|
||||
|
||||
var_check = rdtest.ConstantBufferChecker(
|
||||
self.controller.GetCBufferVariableContents(pipe.GetShader(stage),
|
||||
self.controller.GetCBufferVariableContents(pipe.GetGraphicsPipelineObject(),
|
||||
pipe.GetShader(stage),
|
||||
pipe.GetShaderEntryPoint(stage), 1,
|
||||
cbuf.resourceId, cbuf.byteOffset))
|
||||
|
||||
|
||||
@@ -23,7 +23,8 @@ class GL_CBuffer_Zoo(rdtest.TestCase):
|
||||
cbuf: rd.BoundCBuffer = pipe.GetConstantBuffer(stage, 0, 0)
|
||||
|
||||
var_check = rdtest.ConstantBufferChecker(
|
||||
self.controller.GetCBufferVariableContents(pipe.GetShader(stage),
|
||||
self.controller.GetCBufferVariableContents(pipe.GetGraphicsPipelineObject(),
|
||||
pipe.GetShader(stage),
|
||||
pipe.GetShaderEntryPoint(stage), 0,
|
||||
cbuf.resourceId, cbuf.byteOffset))
|
||||
|
||||
@@ -378,7 +379,8 @@ class GL_CBuffer_Zoo(rdtest.TestCase):
|
||||
cbuf: rd.BoundCBuffer = pipe.GetConstantBuffer(stage, 1, 0)
|
||||
|
||||
var_check = rdtest.ConstantBufferChecker(
|
||||
self.controller.GetCBufferVariableContents(pipe.GetShader(stage),
|
||||
self.controller.GetCBufferVariableContents(pipe.GetGraphicsPipelineObject(),
|
||||
pipe.GetShader(stage),
|
||||
pipe.GetShaderEntryPoint(stage), 1,
|
||||
cbuf.resourceId, cbuf.byteOffset))
|
||||
|
||||
|
||||
@@ -24,7 +24,8 @@ class VK_Adv_CBuffer_Zoo(rdtest.TestCase):
|
||||
cbuf: rd.BoundCBuffer = pipe.GetConstantBuffer(stage, 0, 0)
|
||||
|
||||
var_check = rdtest.ConstantBufferChecker(
|
||||
self.controller.GetCBufferVariableContents(pipe.GetShader(stage),
|
||||
self.controller.GetCBufferVariableContents(pipe.GetGraphicsPipelineObject(),
|
||||
pipe.GetShader(stage),
|
||||
pipe.GetShaderEntryPoint(stage), 0,
|
||||
cbuf.resourceId, cbuf.byteOffset))
|
||||
|
||||
|
||||
@@ -30,7 +30,8 @@ class VK_CBuffer_Zoo(rdtest.TestCase):
|
||||
cbuf: rd.BoundCBuffer = pipe.GetConstantBuffer(stage, 0, 0)
|
||||
|
||||
var_check = rdtest.ConstantBufferChecker(
|
||||
self.controller.GetCBufferVariableContents(pipe.GetShader(stage),
|
||||
self.controller.GetCBufferVariableContents(pipe.GetGraphicsPipelineObject(),
|
||||
pipe.GetShader(stage),
|
||||
pipe.GetShaderEntryPoint(stage), 0,
|
||||
cbuf.resourceId, cbuf.byteOffset))
|
||||
|
||||
@@ -321,7 +322,8 @@ class VK_CBuffer_Zoo(rdtest.TestCase):
|
||||
cbuf: rd.BoundCBuffer = pipe.GetConstantBuffer(stage, 1, 0)
|
||||
|
||||
var_check = rdtest.ConstantBufferChecker(
|
||||
self.controller.GetCBufferVariableContents(pipe.GetShader(stage),
|
||||
self.controller.GetCBufferVariableContents(pipe.GetGraphicsPipelineObject(),
|
||||
pipe.GetShader(stage),
|
||||
pipe.GetShaderEntryPoint(stage), 1,
|
||||
cbuf.resourceId, cbuf.byteOffset))
|
||||
|
||||
@@ -359,7 +361,8 @@ class VK_CBuffer_Zoo(rdtest.TestCase):
|
||||
cbuf: rd.BoundCBuffer = pipe.GetConstantBuffer(stage, 0, 0)
|
||||
|
||||
var_check = rdtest.ConstantBufferChecker(
|
||||
self.controller.GetCBufferVariableContents(pipe.GetShader(stage),
|
||||
self.controller.GetCBufferVariableContents(pipe.GetGraphicsPipelineObject(),
|
||||
pipe.GetShader(stage),
|
||||
pipe.GetShaderEntryPoint(stage), 0,
|
||||
cbuf.resourceId, cbuf.byteOffset))
|
||||
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
import renderdoc as rd
|
||||
import rdtest
|
||||
|
||||
|
||||
class VK_Spec_Constants(rdtest.TestCase):
|
||||
demos_test_name = 'VK_Spec_Constants'
|
||||
|
||||
def check_capture(self):
|
||||
# find the first draw
|
||||
draw = self.find_draw("Draw")
|
||||
|
||||
# Make an output so we can pick pixels
|
||||
out: rd.ReplayOutput = self.controller.CreateOutput(rd.CreateHeadlessWindowingData(100, 100), rd.ReplayOutputType.Texture)
|
||||
|
||||
# We should have 4 draws, with spec constant values 0, 1, 2, 3
|
||||
for num_colors in range(4):
|
||||
self.check(draw is not None)
|
||||
|
||||
self.controller.SetFrameEvent(draw.eventId, False)
|
||||
|
||||
pipe: rd.PipeState = self.controller.GetPipelineState()
|
||||
|
||||
shader: rd.ShaderReflection = pipe.GetShaderReflection(rd.ShaderStage.Pixel)
|
||||
|
||||
# uniform buffer and spec constants
|
||||
self.check(len(shader.constantBlocks) == 2)
|
||||
self.check(shader.constantBlocks[0].bufferBacked)
|
||||
self.check(not shader.constantBlocks[1].bufferBacked)
|
||||
self.check(len(shader.constantBlocks[1].variables) == 1)
|
||||
|
||||
# should be an array of num_colors+1 elements
|
||||
array_len = shader.constantBlocks[0].variables[0].type.descriptor.elements
|
||||
if not rdtest.value_compare(array_len, num_colors+1):
|
||||
raise rdtest.TestFailureException("CBuffer variable is array of {}, not {}".format(array_len, num_colors+1))
|
||||
|
||||
if num_colors > 0:
|
||||
cbuf: rd.BoundCBuffer = pipe.GetConstantBuffer(rd.ShaderStage.Pixel, 0, 0)
|
||||
|
||||
cb_vars = self.controller.GetCBufferVariableContents(pipe.GetGraphicsPipelineObject(),
|
||||
pipe.GetShader(rd.ShaderStage.Pixel),
|
||||
pipe.GetShaderEntryPoint(rd.ShaderStage.Pixel), 0,
|
||||
cbuf.resourceId, cbuf.byteOffset)
|
||||
|
||||
self.check(len(cb_vars) == 1)
|
||||
|
||||
if not rdtest.value_compare(len(cb_vars[0].members), num_colors+1):
|
||||
raise rdtest.TestFailureException("CBuffer variable is array of {}, not {}".format(len(cb_vars[0].members), num_colors+1))
|
||||
|
||||
for col in range(num_colors):
|
||||
expected = [0.0, 0.0, 0.0, 0.0]
|
||||
expected[col] = 1.0
|
||||
|
||||
val = [i for i in cb_vars[0].members[col].value.fv[0:4]]
|
||||
|
||||
if not rdtest.value_compare(val, expected):
|
||||
raise rdtest.TestFailureException("Cbuffer[{}] value {} doesn't match expectation {}".format(col, val, expected))
|
||||
|
||||
rdtest.log.success("Draw with {} colors uniform buffer is as expected".format(num_colors))
|
||||
|
||||
cbuf: rd.BoundCBuffer = pipe.GetConstantBuffer(rd.ShaderStage.Pixel, 1, 0)
|
||||
|
||||
cb_vars = self.controller.GetCBufferVariableContents(pipe.GetGraphicsPipelineObject(),
|
||||
pipe.GetShader(rd.ShaderStage.Pixel),
|
||||
pipe.GetShaderEntryPoint(rd.ShaderStage.Pixel), 1,
|
||||
cbuf.resourceId, cbuf.byteOffset)
|
||||
|
||||
self.check(len(cb_vars) == 1)
|
||||
|
||||
if not rdtest.value_compare(cb_vars[0].value.i.x, num_colors):
|
||||
raise rdtest.TestFailureException("Spec constant is {}, not {}".format(cb_vars[0].value.i.x, num_colors))
|
||||
|
||||
rdtest.log.success("Draw with {} colors specialisation constant is as expected".format(num_colors))
|
||||
|
||||
tex = rd.TextureDisplay()
|
||||
tex.resourceId = pipe.GetOutputTargets()[0].resourceId
|
||||
out.SetTextureDisplay(tex)
|
||||
|
||||
view = pipe.GetViewport(0)
|
||||
|
||||
# Sample the centre of the viewport
|
||||
picked: rd.PixelValue = out.PickPixel(tex.resourceId, False,
|
||||
int(view.x) + int(view.width / 2), int(view.height / 2), 0, 0, 0)
|
||||
|
||||
# the first num_colors components should be 0.6, the rest should be 0.1 (alpha is always 1.0)
|
||||
expected = [0.0, 0.0, 0.0, 1.0]
|
||||
for col in range(num_colors):
|
||||
expected[col] += 1.0
|
||||
|
||||
if not rdtest.value_compare(picked.floatValue, expected):
|
||||
raise rdtest.TestFailureException("Picked value {} doesn't match expectation {}".format(picked.floatValue, expected))
|
||||
|
||||
rdtest.log.success("Draw with {} colors picked value is as expected".format(num_colors))
|
||||
|
||||
draw = draw.next
|
||||
|
||||
out.Shutdown()
|
||||
Reference in New Issue
Block a user