mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-23 06:56:40 +00:00
Remove samplers from ReadOnlyResources array, put them in their own list
This commit is contained in:
@@ -876,7 +876,7 @@ void D3D11PipelineStateViewer::setShaderState(const D3D11Pipe::Shader &stage, QL
|
||||
const ShaderResource &res = shaderDetails->ReadOnlyResources[b];
|
||||
const BindpointMap &bind = mapping.ReadOnlyResources[b];
|
||||
|
||||
if(!res.IsSampler && res.IsReadOnly && bind.bind == i)
|
||||
if(bind.bind == i)
|
||||
{
|
||||
shaderInput = &res;
|
||||
map = &bind;
|
||||
@@ -898,17 +898,17 @@ void D3D11PipelineStateViewer::setShaderState(const D3D11Pipe::Shader &stage, QL
|
||||
{
|
||||
const D3D11Pipe::Sampler &s = stage.Samplers[i];
|
||||
|
||||
const ShaderResource *shaderInput = NULL;
|
||||
const ShaderSampler *shaderInput = NULL;
|
||||
const BindpointMap *map = NULL;
|
||||
|
||||
if(shaderDetails)
|
||||
{
|
||||
for(int b = 0; b < shaderDetails->ReadOnlyResources.count; b++)
|
||||
for(int b = 0; b < shaderDetails->Samplers.count; b++)
|
||||
{
|
||||
const ShaderResource &res = shaderDetails->ReadOnlyResources[b];
|
||||
const BindpointMap &bind = mapping.ReadOnlyResources[b];
|
||||
const ShaderSampler &res = shaderDetails->Samplers[b];
|
||||
const BindpointMap &bind = mapping.Samplers[b];
|
||||
|
||||
if(res.IsSampler && bind.bind == i)
|
||||
if(bind.bind == i)
|
||||
{
|
||||
shaderInput = &res;
|
||||
map = &bind;
|
||||
@@ -1907,7 +1907,7 @@ void D3D11PipelineStateViewer::resource_itemActivated(RDTreeWidgetItem *item, in
|
||||
{
|
||||
for(const ShaderResource &res : searchstage->ShaderDetails->ReadWriteResources)
|
||||
{
|
||||
if(!res.IsTexture && !res.IsSampler && res.bindPoint == bind)
|
||||
if(!res.IsTexture && res.bindPoint == bind)
|
||||
{
|
||||
stage = searchstage;
|
||||
break;
|
||||
@@ -1925,7 +1925,7 @@ void D3D11PipelineStateViewer::resource_itemActivated(RDTreeWidgetItem *item, in
|
||||
|
||||
for(const ShaderResource &res : resArray)
|
||||
{
|
||||
if(!res.IsTexture && !res.IsSampler && res.bindPoint == bind)
|
||||
if(!res.IsTexture && res.bindPoint == bind)
|
||||
{
|
||||
shaderRes = &res;
|
||||
break;
|
||||
@@ -2319,7 +2319,7 @@ QVariantList D3D11PipelineStateViewer::exportViewHTML(const D3D11Pipe::View &vie
|
||||
{
|
||||
for(const ShaderResource &bind : refl->ReadOnlyResources)
|
||||
{
|
||||
if(!bind.IsSampler && bind.bindPoint == i)
|
||||
if(bind.bindPoint == i)
|
||||
{
|
||||
shaderInput = &bind;
|
||||
break;
|
||||
|
||||
@@ -646,7 +646,7 @@ void D3D12PipelineStateViewer::addResourceRow(const D3D12ViewTag &view,
|
||||
if(b.bind <= view.reg)
|
||||
regMatch = (b.arraySize == ~0U) || (b.bind + (int)b.arraySize > view.reg);
|
||||
|
||||
if(b.bindset == view.space && regMatch && !res[i].IsSampler)
|
||||
if(b.bindset == view.space && regMatch)
|
||||
{
|
||||
bind = &b;
|
||||
shaderInput = &res[i];
|
||||
@@ -976,14 +976,14 @@ void D3D12PipelineStateViewer::setShaderState(const D3D12Pipe::Shader &stage, QL
|
||||
continue;
|
||||
|
||||
const BindpointMap *bind = NULL;
|
||||
const ShaderResource *shaderInput = NULL;
|
||||
const ShaderSampler *shaderInput = NULL;
|
||||
|
||||
if(stage.ShaderDetails)
|
||||
{
|
||||
for(int i = 0; i < stage.BindpointMapping.ReadOnlyResources.count; i++)
|
||||
for(int i = 0; i < stage.BindpointMapping.Samplers.count; i++)
|
||||
{
|
||||
const BindpointMap &b = stage.BindpointMapping.ReadOnlyResources[i];
|
||||
const ShaderResource &res = stage.ShaderDetails->ReadOnlyResources[i];
|
||||
const BindpointMap &b = stage.BindpointMapping.Samplers[i];
|
||||
const ShaderSampler &res = stage.ShaderDetails->Samplers[i];
|
||||
|
||||
bool regMatch = b.bind == reg;
|
||||
|
||||
@@ -992,7 +992,7 @@ void D3D12PipelineStateViewer::setShaderState(const D3D12Pipe::Shader &stage, QL
|
||||
if(b.bind <= reg)
|
||||
regMatch = (b.arraySize == ~0U) || (b.bind + (int)b.arraySize > reg);
|
||||
|
||||
if(b.bindset == space && regMatch && res.IsSampler)
|
||||
if(b.bindset == space && regMatch)
|
||||
{
|
||||
bind = &b;
|
||||
shaderInput = &res;
|
||||
@@ -1774,8 +1774,7 @@ void D3D12PipelineStateViewer::resource_itemActivated(RDTreeWidgetItem *item, in
|
||||
|
||||
for(int i = 0; i < bindArray.count; i++)
|
||||
{
|
||||
if(bindArray[i].bindset == view.space && bindArray[i].bind == view.reg &&
|
||||
!resArray[i].IsSampler)
|
||||
if(bindArray[i].bindset == view.space && bindArray[i].bind == view.reg)
|
||||
{
|
||||
shaderRes = &resArray[i];
|
||||
break;
|
||||
@@ -2423,7 +2422,7 @@ void D3D12PipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const D3D12Pipe
|
||||
if(b.bind <= reg)
|
||||
regMatch = (b.arraySize == ~0U) || (b.bind + (int)b.arraySize > reg);
|
||||
|
||||
if(b.bindset == space && regMatch && !res.IsReadOnly && !res.IsSampler)
|
||||
if(b.bindset == space && regMatch)
|
||||
{
|
||||
shaderInput = &res;
|
||||
break;
|
||||
@@ -2473,10 +2472,10 @@ void D3D12PipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const D3D12Pipe
|
||||
|
||||
if(sh.ShaderDetails)
|
||||
{
|
||||
for(int i = 0; i < sh.BindpointMapping.ReadOnlyResources.count; i++)
|
||||
for(int i = 0; i < sh.BindpointMapping.ReadWriteResources.count; i++)
|
||||
{
|
||||
const BindpointMap &b = sh.BindpointMapping.ReadOnlyResources[i];
|
||||
const ShaderResource &res = sh.ShaderDetails->ReadOnlyResources[i];
|
||||
const BindpointMap &b = sh.BindpointMapping.ReadWriteResources[i];
|
||||
const ShaderResource &res = sh.ShaderDetails->ReadWriteResources[i];
|
||||
|
||||
bool regMatch = b.bind == reg;
|
||||
|
||||
@@ -2485,7 +2484,7 @@ void D3D12PipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const D3D12Pipe
|
||||
if(b.bind <= reg)
|
||||
regMatch = (b.arraySize == ~0U) || (b.bind + (int)b.arraySize > reg);
|
||||
|
||||
if(b.bindset == space && regMatch && !res.IsReadOnly && !res.IsSampler)
|
||||
if(b.bindset == space && regMatch)
|
||||
{
|
||||
shaderInput = &res;
|
||||
break;
|
||||
@@ -2531,14 +2530,14 @@ void D3D12PipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const D3D12Pipe
|
||||
if(s.RootElement == ~0U)
|
||||
continue;
|
||||
|
||||
const ShaderResource *shaderInput = NULL;
|
||||
const ShaderSampler *shaderInput = NULL;
|
||||
|
||||
if(sh.ShaderDetails)
|
||||
{
|
||||
for(int i = 0; i < sh.BindpointMapping.ReadOnlyResources.count; i++)
|
||||
for(int i = 0; i < sh.BindpointMapping.Samplers.count; i++)
|
||||
{
|
||||
const BindpointMap &b = sh.BindpointMapping.ReadOnlyResources[i];
|
||||
const ShaderResource &res = sh.ShaderDetails->ReadOnlyResources[i];
|
||||
const BindpointMap &b = sh.BindpointMapping.Samplers[i];
|
||||
const ShaderSampler &res = sh.ShaderDetails->Samplers[i];
|
||||
|
||||
bool regMatch = b.bind == reg;
|
||||
|
||||
@@ -2547,7 +2546,7 @@ void D3D12PipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const D3D12Pipe
|
||||
if(b.bind <= reg)
|
||||
regMatch = (b.arraySize == ~0U) || (b.bind + (int)b.arraySize > reg);
|
||||
|
||||
if(b.bindset == space && regMatch && res.IsSampler)
|
||||
if(b.bindset == space && regMatch)
|
||||
{
|
||||
shaderInput = &res;
|
||||
break;
|
||||
|
||||
@@ -618,49 +618,47 @@ QString PipelineStateViewer::GenerateHLSLStub(const ShaderReflection *shaderDeta
|
||||
lit("Texture2DMSArray"), lit("Texture3D"), lit("TextureCube"), lit("TextureCubeArray"),
|
||||
};
|
||||
|
||||
for(const ShaderSampler &samp : shaderDetails->Samplers)
|
||||
{
|
||||
hlsl += lit("//SamplerComparisonState %1 : register(s%2); // can't disambiguate\n"
|
||||
"SamplerState %1 : register(s%2); // can't disambiguate\n")
|
||||
.arg(samp.name)
|
||||
.arg(samp.bindPoint);
|
||||
}
|
||||
|
||||
for(int i = 0; i < 2; i++)
|
||||
{
|
||||
const rdctype::array<ShaderResource> &resources =
|
||||
(i == 0 ? shaderDetails->ReadOnlyResources : shaderDetails->ReadWriteResources);
|
||||
for(const ShaderResource &res : resources)
|
||||
{
|
||||
if(res.IsSampler)
|
||||
char regChar = 't';
|
||||
|
||||
if(i == 1)
|
||||
{
|
||||
hlsl += lit("//SamplerComparisonState %1 : register(s%2); // can't disambiguate\n"
|
||||
"SamplerState %1 : register(s%2); // can't disambiguate\n")
|
||||
hlsl += lit("RW");
|
||||
regChar = 'u';
|
||||
}
|
||||
|
||||
if(res.IsTexture)
|
||||
{
|
||||
hlsl += lit("%1<%2> %3 : register(%4%5);\n")
|
||||
.arg(textureDim[(size_t)res.resType])
|
||||
.arg(res.variableType.descriptor.name)
|
||||
.arg(res.name)
|
||||
.arg(QLatin1Char(regChar))
|
||||
.arg(res.bindPoint);
|
||||
}
|
||||
else
|
||||
{
|
||||
char regChar = 't';
|
||||
if(res.variableType.descriptor.rows > 1)
|
||||
hlsl += lit("Structured");
|
||||
|
||||
if(i == 1)
|
||||
{
|
||||
hlsl += lit("RW");
|
||||
regChar = 'u';
|
||||
}
|
||||
|
||||
if(res.IsTexture)
|
||||
{
|
||||
hlsl += lit("%1<%2> %3 : register(%4%5);\n")
|
||||
.arg(textureDim[(size_t)res.resType])
|
||||
.arg(res.variableType.descriptor.name)
|
||||
.arg(res.name)
|
||||
.arg(QLatin1Char(regChar))
|
||||
.arg(res.bindPoint);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(res.variableType.descriptor.rows > 1)
|
||||
hlsl += lit("Structured");
|
||||
|
||||
hlsl += lit("Buffer<%1> %2 : register(%3%4);\n")
|
||||
.arg(res.variableType.descriptor.name)
|
||||
.arg(res.name)
|
||||
.arg(QLatin1Char(regChar))
|
||||
.arg(res.bindPoint);
|
||||
}
|
||||
hlsl += lit("Buffer<%1> %2 : register(%3%4);\n")
|
||||
.arg(res.variableType.descriptor.name)
|
||||
.arg(res.name)
|
||||
.arg(QLatin1Char(regChar))
|
||||
.arg(res.bindPoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -712,14 +712,10 @@ void VulkanPipelineStateViewer::addResourceRow(ShaderReflection *shaderDetails,
|
||||
}
|
||||
else
|
||||
{
|
||||
if(shaderRes->IsSampler)
|
||||
bindType = BindType::Sampler;
|
||||
else if(shaderRes->IsSampler && shaderRes->IsTexture)
|
||||
bindType = BindType::ImageSampler;
|
||||
else if(shaderRes->resType == TextureDim::Buffer)
|
||||
bindType = BindType::ReadOnlyTBuffer;
|
||||
if(shaderRes->resType == TextureDim::Buffer)
|
||||
bindType = isrw ? BindType::ReadWriteBuffer : BindType::ReadOnlyBuffer;
|
||||
else
|
||||
bindType = BindType::ReadOnlyImage;
|
||||
bindType = isrw ? BindType::ReadWriteImage : BindType::ReadOnlyImage;
|
||||
}
|
||||
|
||||
bool usedSlot = bindMap != NULL && bindMap->used;
|
||||
|
||||
@@ -1024,9 +1024,6 @@ RDTreeWidgetItem *ShaderViewer::makeResourceRegister(const BindpointMap &bind, u
|
||||
const TextureDescription *tex = m_Ctx.GetTexture(bound.Id);
|
||||
const BufferDescription *buf = m_Ctx.GetBuffer(bound.Id);
|
||||
|
||||
if(res.IsSampler)
|
||||
return NULL;
|
||||
|
||||
QChar regChar(QLatin1Char('u'));
|
||||
|
||||
if(res.IsReadOnly)
|
||||
|
||||
@@ -2006,33 +2006,18 @@ void TextureViewer::InitStageResourcePreviews(ShaderStage stage,
|
||||
CompType typeHint = resArray != NULL ? resArray->at(arrayIdx).typeHint : CompType::Typeless;
|
||||
|
||||
bool used = key.used;
|
||||
bool samplerBind = false;
|
||||
bool otherBind = false;
|
||||
|
||||
QString bindName;
|
||||
|
||||
for(int b = 0; b < resourceDetails.count; b++)
|
||||
for(const ShaderResource &bind : resourceDetails)
|
||||
{
|
||||
const ShaderResource &bind = resourceDetails[b];
|
||||
if(bind.bindPoint == idx && bind.IsReadOnly)
|
||||
{
|
||||
bindName = bind.name;
|
||||
otherBind = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if(bind.bindPoint == idx)
|
||||
{
|
||||
if(bind.IsSampler && !bind.IsReadOnly)
|
||||
samplerBind = true;
|
||||
else
|
||||
otherBind = true;
|
||||
bindName = bind.name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(samplerBind && !otherBind)
|
||||
continue;
|
||||
|
||||
if(copy)
|
||||
{
|
||||
used = true;
|
||||
|
||||
@@ -399,10 +399,30 @@ specialisation constants.
|
||||
|
||||
DECLARE_REFLECTION_STRUCT(ConstantBlock);
|
||||
|
||||
DOCUMENT(R"(Contains the information for a separate sampler in a shader. If the API doesn't have
|
||||
the concept of separate samplers, this struct will be unused and only :class:`ShaderResource` is
|
||||
relevant.
|
||||
|
||||
.. note:: that constant blocks will not have a shader resource entry, see :class:`ConstantBlock`.
|
||||
)");
|
||||
struct ShaderSampler
|
||||
{
|
||||
DOCUMENT("The name of this sampler.");
|
||||
rdctype::str name;
|
||||
|
||||
DOCUMENT(R"(The bindpoint for this block. This is an index in either the
|
||||
:data:`ShaderBindpointMapping.Samplers` list.
|
||||
)");
|
||||
int32_t bindPoint;
|
||||
};
|
||||
|
||||
DECLARE_REFLECTION_STRUCT(ShaderSampler);
|
||||
|
||||
DOCUMENT(R"(Contains the information for a shader resource that is made accessible to shaders
|
||||
directly by means of the API resource binding system.
|
||||
|
||||
.. note:: that constant blocks will not have a shader resource entry, see :class:`ConstantBlock`.
|
||||
.. note:: that constant blocks and samplers will not have a shader resource entry, see
|
||||
:class:`ConstantBlock` and :class:`ShaderSampler`.
|
||||
)");
|
||||
struct ShaderResource
|
||||
{
|
||||
@@ -421,14 +441,6 @@ struct ShaderResource
|
||||
)");
|
||||
int32_t bindPoint;
|
||||
|
||||
DOCUMENT(R"(``True`` if this resource is a sampler.
|
||||
|
||||
If the API has no concept of separate samplers, this will always be ``False``.
|
||||
|
||||
.. note:: this is not exclusive with the other flags in the case of e.g. combined sampler/texture
|
||||
objects.
|
||||
)");
|
||||
bool IsSampler;
|
||||
DOCUMENT(R"(``True`` if this resource is a texture, otherwise it is a buffer or sampler (see
|
||||
:data:`IsSampler`).
|
||||
)");
|
||||
@@ -503,6 +515,9 @@ struct ShaderReflection
|
||||
DOCUMENT("A list of :class:`ConstantBlock` with the shader's constant bindings.");
|
||||
rdctype::array<ConstantBlock> ConstantBlocks;
|
||||
|
||||
DOCUMENT("A list of :class:`ShaderSampler` with the shader's samplers.");
|
||||
rdctype::array<ShaderSampler> Samplers;
|
||||
|
||||
DOCUMENT("A list of :class:`ShaderResource` with the shader's read-only resources.");
|
||||
rdctype::array<ShaderResource> ReadOnlyResources;
|
||||
DOCUMENT("A list of :class:`ShaderResource` with the shader's read-write resources.");
|
||||
@@ -571,19 +586,8 @@ API specific details:
|
||||
|
||||
:data:`BindpointMap.arraySize` is likewise unused as D3D11 doesn't have arrayed resource bindings.
|
||||
|
||||
The :data:`BindpointMap.bind` value corresponds directly to the index in the appropriate resource
|
||||
list.
|
||||
|
||||
One important thing to note is that samplers are included with read only resources. This means
|
||||
consumers wanting to map to API bindpoints should know and expect that the
|
||||
:data:`ReadOnlyResources` list contains potentially duplicate :class:`BindpointMap`, with one
|
||||
being a SRV and one a sampler.
|
||||
|
||||
Note that D3D11 currently uses an identity bindpoint mapping, such that the index in the bindpoint
|
||||
array is equal to the register, even if it's sparse. E.g. textures ``0`` and ``4`` will be in
|
||||
bindpoint maps ``0`` and ``4`` with three empty unused maps in ``1``, ``2``, and ``3``. This is
|
||||
not contractual and should not be relied upon, in future the bindpoint map may be only two
|
||||
elements that list ``0`` and ``4``, with the shader bindpoints then being ``0`` and ``1``.
|
||||
:data:`BindpointMap.bind` refers to the register/slot binding within the appropriate type (SRVs for
|
||||
read-only resources, UAV for read-write resources, samplers/constant buffers in each type).
|
||||
|
||||
* OpenGL - Similarly to D3D11, :data:`BindpointMap.bindset` and :data:`BindpointMap.arraySize` are
|
||||
unused as OpenGL does not have true binding sets or array resource binds.
|
||||
@@ -594,9 +598,8 @@ API specific details:
|
||||
the :data:`ReadWriteResources` list. The index is the uniform value of the binding. Since no
|
||||
objects are namespaced by shader stage, the same value in two shaders refers to the same binding.
|
||||
|
||||
* Direct3D12 - As with 11 above, samplers are included in the read only resources array. Likewise
|
||||
since D3D12 doesn't have true resource arrays (they are linearised into sequential registers)
|
||||
:data:`BindpointMap.arraySize` is not used.
|
||||
* Direct3D12 - Since D3D12 doesn't have true resource arrays (they are linearised into sequential
|
||||
registers) :data:`BindpointMap.arraySize` is not used.
|
||||
|
||||
:data:`BindpointMap.bindset` corresponds to register spaces, with :data:`BindpointMap.bind` then
|
||||
mapping to the register within that space. The root signature then maps these registers to
|
||||
@@ -619,6 +622,11 @@ struct ShaderBindpointMapping
|
||||
)");
|
||||
rdctype::array<BindpointMap> ConstantBlocks;
|
||||
|
||||
DOCUMENT(R"(Provides a list of :class:`BindpointMap` entries for remapping the
|
||||
:data:`ShaderReflection.Samplers` list.
|
||||
)");
|
||||
rdctype::array<BindpointMap> Samplers;
|
||||
|
||||
DOCUMENT(R"(Provides a list of :class:`BindpointMap` entries for remapping the
|
||||
:data:`ShaderReflection.ReadOnlyResources` list.
|
||||
)");
|
||||
|
||||
@@ -128,10 +128,11 @@ void Serialiser::Serialise(const char *name, ShaderBindpointMapping &el)
|
||||
{
|
||||
Serialise("", el.InputAttributes);
|
||||
Serialise("", el.ConstantBlocks);
|
||||
Serialise("", el.Samplers);
|
||||
Serialise("", el.ReadOnlyResources);
|
||||
Serialise("", el.ReadWriteResources);
|
||||
|
||||
SIZE_CHECK(64);
|
||||
SIZE_CHECK(80);
|
||||
}
|
||||
|
||||
template <>
|
||||
@@ -193,10 +194,18 @@ void Serialiser::Serialise(const char *name, ConstantBlock &el)
|
||||
SIZE_CHECK(48);
|
||||
}
|
||||
|
||||
template <>
|
||||
void Serialiser::Serialise(const char *name, ShaderSampler &el)
|
||||
{
|
||||
Serialise("", el.name);
|
||||
Serialise("", el.bindPoint);
|
||||
|
||||
SIZE_CHECK(24);
|
||||
}
|
||||
|
||||
template <>
|
||||
void Serialiser::Serialise(const char *name, ShaderResource &el)
|
||||
{
|
||||
Serialise("", el.IsSampler);
|
||||
Serialise("", el.IsTexture);
|
||||
Serialise("", el.IsReadOnly);
|
||||
Serialise("", el.resType);
|
||||
@@ -241,12 +250,14 @@ void Serialiser::Serialise(const char *name, ShaderReflection &el)
|
||||
|
||||
Serialise("", el.ConstantBlocks);
|
||||
|
||||
Serialise("", el.Samplers);
|
||||
|
||||
Serialise("", el.ReadOnlyResources);
|
||||
Serialise("", el.ReadWriteResources);
|
||||
|
||||
Serialise("", el.Interfaces);
|
||||
|
||||
SIZE_CHECK(184);
|
||||
SIZE_CHECK(200);
|
||||
}
|
||||
|
||||
template <>
|
||||
@@ -401,7 +412,7 @@ void Serialiser::Serialise(const char *name, D3D11Pipe::Shader &el)
|
||||
Serialise("", el.ConstantBuffers);
|
||||
Serialise("", el.ClassInstances);
|
||||
|
||||
SIZE_CHECK(192);
|
||||
SIZE_CHECK(208);
|
||||
}
|
||||
|
||||
template <>
|
||||
@@ -496,7 +507,7 @@ void Serialiser::Serialise(const char *name, D3D11Pipe::State &el)
|
||||
Serialise("", el.m_RS);
|
||||
Serialise("", el.m_OM);
|
||||
|
||||
SIZE_CHECK(1560);
|
||||
SIZE_CHECK(1656);
|
||||
}
|
||||
|
||||
#pragma endregion D3D11 pipeline state
|
||||
@@ -616,7 +627,7 @@ void Serialiser::Serialise(const char *name, D3D12Pipe::Shader &el)
|
||||
Serialise("", el.stage);
|
||||
Serialise("", el.Spaces);
|
||||
|
||||
SIZE_CHECK(104);
|
||||
SIZE_CHECK(120);
|
||||
}
|
||||
|
||||
template <>
|
||||
@@ -735,7 +746,7 @@ void Serialiser::Serialise(const char *name, D3D12Pipe::State &el)
|
||||
|
||||
Serialise("", el.Resources);
|
||||
|
||||
SIZE_CHECK(1080);
|
||||
SIZE_CHECK(1176);
|
||||
}
|
||||
|
||||
#pragma endregion D3D12 pipeline state
|
||||
@@ -789,7 +800,7 @@ void Serialiser::Serialise(const char *name, GLPipe::Shader &el)
|
||||
if(m_Mode == READING)
|
||||
el.ShaderDetails = NULL;
|
||||
|
||||
SIZE_CHECK(176);
|
||||
SIZE_CHECK(192);
|
||||
}
|
||||
|
||||
template <>
|
||||
@@ -967,7 +978,7 @@ void Serialiser::Serialise(const char *name, GLPipe::State &el)
|
||||
|
||||
Serialise("", el.m_Hints);
|
||||
|
||||
SIZE_CHECK(1832);
|
||||
SIZE_CHECK(1928);
|
||||
}
|
||||
|
||||
#pragma endregion OpenGL pipeline state
|
||||
@@ -1090,7 +1101,7 @@ void Serialiser::Serialise(const char *name, VKPipe::Shader &el)
|
||||
|
||||
Serialise("", el.specialization);
|
||||
|
||||
SIZE_CHECK(144);
|
||||
SIZE_CHECK(160);
|
||||
}
|
||||
|
||||
template <>
|
||||
@@ -1251,7 +1262,7 @@ void Serialiser::Serialise(const char *name, VKPipe::State &el)
|
||||
|
||||
Serialise("", el.images);
|
||||
|
||||
SIZE_CHECK(1328);
|
||||
SIZE_CHECK(1424);
|
||||
}
|
||||
|
||||
#pragma endregion Vulkan pipeline state
|
||||
|
||||
@@ -853,7 +853,7 @@ void D3D11DebugManager::CreateShaderGlobalState(ShaderDebug::GlobalState &global
|
||||
global.srvs[i].format.stride = bufdesc.StructureByteStride;
|
||||
|
||||
// if we didn't get a type from the SRV description, try to pull it from the declaration
|
||||
for(const DXBC::ShaderInputBind &bind : dxbc->m_Resources)
|
||||
for(const DXBC::ShaderInputBind &bind : dxbc->m_SRVs)
|
||||
{
|
||||
if(bind.reg == (uint32_t)i && bind.dimension == DXBC::ShaderInputBind::DIM_BUFFER &&
|
||||
bind.retType < DXBC::ShaderInputBind::RETTYPE_MIXED &&
|
||||
|
||||
@@ -1519,17 +1519,9 @@ bool D3D11RenderState::shader::Used_SRV(uint32_t slot) const
|
||||
if(dxbc == NULL)
|
||||
return true;
|
||||
|
||||
for(size_t i = 0; i < dxbc->m_Resources.size(); i++)
|
||||
{
|
||||
if(dxbc->m_Resources[i].reg == slot &&
|
||||
(dxbc->m_Resources[i].type == DXBC::ShaderInputBind::TYPE_TEXTURE ||
|
||||
dxbc->m_Resources[i].type == DXBC::ShaderInputBind::TYPE_STRUCTURED ||
|
||||
dxbc->m_Resources[i].type == DXBC::ShaderInputBind::TYPE_TBUFFER ||
|
||||
dxbc->m_Resources[i].type == DXBC::ShaderInputBind::TYPE_BYTEADDRESS))
|
||||
{
|
||||
for(const DXBC::ShaderInputBind &bind : dxbc->m_SRVs)
|
||||
if(bind.reg == slot)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -1547,19 +1539,9 @@ bool D3D11RenderState::shader::Used_UAV(uint32_t slot) const
|
||||
if(dxbc == NULL)
|
||||
return true;
|
||||
|
||||
for(size_t i = 0; i < dxbc->m_Resources.size(); i++)
|
||||
{
|
||||
if(dxbc->m_Resources[i].reg == slot &&
|
||||
(dxbc->m_Resources[i].type == DXBC::ShaderInputBind::TYPE_UAV_APPEND_STRUCTURED ||
|
||||
dxbc->m_Resources[i].type == DXBC::ShaderInputBind::TYPE_UAV_CONSUME_STRUCTURED ||
|
||||
dxbc->m_Resources[i].type == DXBC::ShaderInputBind::TYPE_UAV_RWBYTEADDRESS ||
|
||||
dxbc->m_Resources[i].type == DXBC::ShaderInputBind::TYPE_UAV_RWSTRUCTURED ||
|
||||
dxbc->m_Resources[i].type == DXBC::ShaderInputBind::TYPE_UAV_RWSTRUCTURED_WITH_COUNTER ||
|
||||
dxbc->m_Resources[i].type == DXBC::ShaderInputBind::TYPE_UAV_RWTYPED))
|
||||
{
|
||||
for(const DXBC::ShaderInputBind &bind : dxbc->m_UAVs)
|
||||
if(bind.reg == slot)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -922,7 +922,6 @@ void MakeShaderReflection(const GLHookSet &gl, GLenum shadType, GLuint sepProg,
|
||||
gl.glGetProgramResourceiv(sepProg, eGL_UNIFORM, u, numProps, resProps, numProps, NULL, values);
|
||||
|
||||
ShaderResource res;
|
||||
res.IsSampler = false; // no separate sampler objects in GL
|
||||
res.IsReadOnly = true;
|
||||
res.IsTexture = true;
|
||||
res.variableType.descriptor.rows = 1;
|
||||
@@ -1465,7 +1464,6 @@ void MakeShaderReflection(const GLHookSet &gl, GLenum shadType, GLuint sepProg,
|
||||
gl.glGetProgramResourceName(sepProg, eGL_SHADER_STORAGE_BLOCK, u, len + 1, NULL, nm);
|
||||
|
||||
ShaderResource res;
|
||||
res.IsSampler = false;
|
||||
res.IsReadOnly = false;
|
||||
res.IsTexture = false;
|
||||
res.resType = TextureDim::Buffer;
|
||||
|
||||
@@ -982,14 +982,22 @@ string ASMOperand::toString(DXBCFile *dxbc, ToString flags) const
|
||||
{
|
||||
uint32_t idx = (uint32_t)indices[0].index;
|
||||
|
||||
for(const ShaderInputBind &b : dxbc->m_Resources)
|
||||
{
|
||||
if(b.reg != idx || b.space != 0)
|
||||
continue;
|
||||
vector<ShaderInputBind> *list = NULL;
|
||||
|
||||
if((type == TYPE_RESOURCE && b.IsROResource()) || (type == TYPE_SAMPLER && b.IsSampler()) ||
|
||||
(type == TYPE_UNORDERED_ACCESS_VIEW && b.IsUAV()))
|
||||
if(type == TYPE_RESOURCE)
|
||||
list = &dxbc->m_SRVs;
|
||||
else if(type == TYPE_UNORDERED_ACCESS_VIEW)
|
||||
list = &dxbc->m_UAVs;
|
||||
else if(type == TYPE_SAMPLER)
|
||||
list = &dxbc->m_Samplers;
|
||||
|
||||
if(list)
|
||||
{
|
||||
for(const ShaderInputBind &b : *list)
|
||||
{
|
||||
if(b.reg != idx || b.space != 0)
|
||||
continue;
|
||||
|
||||
if(decl)
|
||||
regstr = str;
|
||||
str = b.name;
|
||||
|
||||
@@ -594,7 +594,9 @@ DXBCFile::DXBCFile(const void *ByteCode, size_t ByteCodeLength)
|
||||
else if(h->targetShaderStage == 0x4353) // 'CS'
|
||||
m_Type = D3D11_ShaderType_Compute;
|
||||
|
||||
m_Resources.reserve(h->resources.count);
|
||||
m_SRVs.reserve(h->resources.count);
|
||||
m_UAVs.reserve(h->resources.count);
|
||||
m_Samplers.reserve(h->resources.count);
|
||||
|
||||
struct CBufferBind
|
||||
{
|
||||
@@ -639,7 +641,7 @@ DXBCFile::DXBCFile(const void *ByteCode, size_t ByteCodeLength)
|
||||
// for cbuffers the names can be duplicated, so handle this by assuming
|
||||
// the order will match between binding declaration and cbuffer declaration
|
||||
// and append _s onto each subsequent buffer name
|
||||
if(desc.type == ShaderInputBind::TYPE_CBUFFER)
|
||||
if(desc.IsCBuffer())
|
||||
{
|
||||
string cname = desc.name;
|
||||
|
||||
@@ -652,8 +654,22 @@ DXBCFile::DXBCFile(const void *ByteCode, size_t ByteCodeLength)
|
||||
cb.bindCount = desc.bindCount;
|
||||
cbufferbinds[cname] = cb;
|
||||
}
|
||||
|
||||
m_Resources.push_back(desc);
|
||||
else if(desc.IsSampler())
|
||||
{
|
||||
m_Samplers.push_back(desc);
|
||||
}
|
||||
else if(desc.IsSRV())
|
||||
{
|
||||
m_SRVs.push_back(desc);
|
||||
}
|
||||
else if(desc.IsUAV())
|
||||
{
|
||||
m_UAVs.push_back(desc);
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCERR("Unexpected type of resource: %u", desc.type);
|
||||
}
|
||||
}
|
||||
|
||||
// Expand out any array resources. We deliberately place these at the end of the resources
|
||||
@@ -666,31 +682,35 @@ DXBCFile::DXBCFile(const void *ByteCode, size_t ByteCodeLength)
|
||||
// Note we preserve the arrays in SM5.1
|
||||
if(h->targetVersion < 0x501)
|
||||
{
|
||||
for(size_t i = 0; i < m_Resources.size();)
|
||||
for(vector<ShaderInputBind> *arr : {&m_SRVs, &m_UAVs, &m_Samplers})
|
||||
{
|
||||
if(m_Resources[i].bindCount > 1)
|
||||
vector<ShaderInputBind> &resArray = *arr;
|
||||
for(size_t i = 0; i < resArray.size();)
|
||||
{
|
||||
ShaderInputBind desc = m_Resources[i];
|
||||
m_Resources.erase(m_Resources.begin() + i);
|
||||
|
||||
string rname = desc.name;
|
||||
uint32_t arraySize = desc.bindCount;
|
||||
|
||||
desc.bindCount = 1;
|
||||
|
||||
for(uint32_t a = 0; a < arraySize; a++)
|
||||
if(resArray[i].bindCount > 1)
|
||||
{
|
||||
desc.name = StringFormat::Fmt("%s[%u]", rname.c_str(), a);
|
||||
m_Resources.push_back(desc);
|
||||
desc.reg++;
|
||||
ShaderInputBind desc = resArray[i];
|
||||
resArray.erase(resArray.begin() + i);
|
||||
|
||||
string rname = desc.name;
|
||||
uint32_t arraySize = desc.bindCount;
|
||||
|
||||
desc.bindCount = 1;
|
||||
|
||||
for(uint32_t a = 0; a < arraySize; a++)
|
||||
{
|
||||
desc.name = StringFormat::Fmt("%s[%u]", rname.c_str(), a);
|
||||
resArray.push_back(desc);
|
||||
desc.reg++;
|
||||
}
|
||||
|
||||
// continue from the i'th element again since
|
||||
// we just removed it.
|
||||
continue;
|
||||
}
|
||||
|
||||
// continue from the i'th element again since
|
||||
// we just removed it.
|
||||
continue;
|
||||
i++;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1071,7 +1091,7 @@ void DXBCFile::GuessResources()
|
||||
desc.bindCount = 0;
|
||||
}
|
||||
|
||||
m_Resources.push_back(desc);
|
||||
m_Samplers.push_back(desc);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -1136,7 +1156,7 @@ void DXBCFile::GuessResources()
|
||||
desc.bindCount = 0;
|
||||
}
|
||||
|
||||
m_Resources.push_back(desc);
|
||||
m_SRVs.push_back(desc);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -1173,7 +1193,10 @@ void DXBCFile::GuessResources()
|
||||
desc.bindCount = 0;
|
||||
}
|
||||
|
||||
m_Resources.push_back(desc);
|
||||
if(dcl.operand.type == TYPE_RESOURCE)
|
||||
m_SRVs.push_back(desc);
|
||||
else
|
||||
m_UAVs.push_back(desc);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -1206,7 +1229,7 @@ void DXBCFile::GuessResources()
|
||||
desc.bindCount = 0;
|
||||
}
|
||||
|
||||
m_Resources.push_back(desc);
|
||||
m_SRVs.push_back(desc);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -1243,7 +1266,7 @@ void DXBCFile::GuessResources()
|
||||
desc.bindCount = 0;
|
||||
}
|
||||
|
||||
m_Resources.push_back(desc);
|
||||
m_UAVs.push_back(desc);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -1302,7 +1325,7 @@ void DXBCFile::GuessResources()
|
||||
desc.bindCount = 0;
|
||||
}
|
||||
|
||||
m_Resources.push_back(desc);
|
||||
m_UAVs.push_back(desc);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -1338,8 +1361,6 @@ void DXBCFile::GuessResources()
|
||||
|
||||
CBuffer cb;
|
||||
|
||||
m_Resources.push_back(desc);
|
||||
|
||||
cb.name = desc.name;
|
||||
|
||||
cb.space = dcl.space;
|
||||
|
||||
@@ -139,7 +139,7 @@ struct ShaderInputBind
|
||||
|
||||
constexpr bool IsCBuffer() const { return type == TYPE_CBUFFER; }
|
||||
constexpr bool IsSampler() const { return type == TYPE_SAMPLER; }
|
||||
constexpr bool IsROResource() const
|
||||
constexpr bool IsSRV() const
|
||||
{
|
||||
return type == TYPE_TBUFFER || type == TYPE_TEXTURE || type == TYPE_STRUCTURED ||
|
||||
type == TYPE_BYTEADDRESS;
|
||||
@@ -369,7 +369,10 @@ public:
|
||||
vector<uint32_t> m_Immediate;
|
||||
|
||||
bool m_GuessedResources;
|
||||
vector<ShaderInputBind> m_Resources;
|
||||
vector<ShaderInputBind> m_SRVs;
|
||||
vector<ShaderInputBind> m_UAVs;
|
||||
|
||||
vector<ShaderInputBind> m_Samplers;
|
||||
|
||||
vector<CBuffer> m_CBuffers;
|
||||
|
||||
|
||||
@@ -108,6 +108,102 @@ static ShaderConstant MakeConstantBufferVariable(const DXBC::CBufferVariable &va
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void MakeResourceList(bool srv, DXBC::DXBCFile *dxbc, const vector<DXBC::ShaderInputBind> &in,
|
||||
rdctype::array<BindpointMap> &mapping,
|
||||
rdctype::array<ShaderResource> &refl)
|
||||
{
|
||||
for(size_t i = 0; i < in.size(); i++)
|
||||
{
|
||||
const DXBC::ShaderInputBind &r = in[i];
|
||||
|
||||
ShaderResource res;
|
||||
res.name = r.name;
|
||||
|
||||
res.IsTexture = (r.type == DXBC::ShaderInputBind::TYPE_TEXTURE &&
|
||||
r.dimension != DXBC::ShaderInputBind::DIM_UNKNOWN &&
|
||||
r.dimension != DXBC::ShaderInputBind::DIM_BUFFER &&
|
||||
r.dimension != DXBC::ShaderInputBind::DIM_BUFFEREX);
|
||||
res.IsReadOnly = srv;
|
||||
|
||||
switch(r.dimension)
|
||||
{
|
||||
default:
|
||||
case DXBC::ShaderInputBind::DIM_UNKNOWN: res.resType = TextureDim::Unknown; break;
|
||||
case DXBC::ShaderInputBind::DIM_BUFFER:
|
||||
case DXBC::ShaderInputBind::DIM_BUFFEREX: res.resType = TextureDim::Buffer; break;
|
||||
case DXBC::ShaderInputBind::DIM_TEXTURE1D: res.resType = TextureDim::Texture1D; break;
|
||||
case DXBC::ShaderInputBind::DIM_TEXTURE1DARRAY:
|
||||
res.resType = TextureDim::Texture1DArray;
|
||||
break;
|
||||
case DXBC::ShaderInputBind::DIM_TEXTURE2D: res.resType = TextureDim::Texture2D; break;
|
||||
case DXBC::ShaderInputBind::DIM_TEXTURE2DARRAY:
|
||||
res.resType = TextureDim::Texture2DArray;
|
||||
break;
|
||||
case DXBC::ShaderInputBind::DIM_TEXTURE2DMS: res.resType = TextureDim::Texture2DMS; break;
|
||||
case DXBC::ShaderInputBind::DIM_TEXTURE2DMSARRAY:
|
||||
res.resType = TextureDim::Texture2DMSArray;
|
||||
break;
|
||||
case DXBC::ShaderInputBind::DIM_TEXTURE3D: res.resType = TextureDim::Texture3D; break;
|
||||
case DXBC::ShaderInputBind::DIM_TEXTURECUBE: res.resType = TextureDim::TextureCube; break;
|
||||
case DXBC::ShaderInputBind::DIM_TEXTURECUBEARRAY:
|
||||
res.resType = TextureDim::TextureCubeArray;
|
||||
break;
|
||||
}
|
||||
|
||||
if(r.retType != DXBC::ShaderInputBind::RETTYPE_UNKNOWN &&
|
||||
r.retType != DXBC::ShaderInputBind::RETTYPE_MIXED &&
|
||||
r.retType != DXBC::ShaderInputBind::RETTYPE_CONTINUED)
|
||||
{
|
||||
res.variableType.descriptor.rows = 1;
|
||||
res.variableType.descriptor.cols = (uint8_t)r.numSamples;
|
||||
res.variableType.descriptor.elements = 1;
|
||||
|
||||
string name;
|
||||
|
||||
switch(r.retType)
|
||||
{
|
||||
case DXBC::ShaderInputBind::RETTYPE_UNORM: name = "unorm float"; break;
|
||||
case DXBC::ShaderInputBind::RETTYPE_SNORM: name = "snorm float"; break;
|
||||
case DXBC::ShaderInputBind::RETTYPE_SINT: name = "int"; break;
|
||||
case DXBC::ShaderInputBind::RETTYPE_UINT: name = "uint"; break;
|
||||
case DXBC::ShaderInputBind::RETTYPE_FLOAT: name = "float"; break;
|
||||
case DXBC::ShaderInputBind::RETTYPE_DOUBLE: name = "double"; break;
|
||||
default: name = "unknown"; break;
|
||||
}
|
||||
|
||||
name += StringFormat::Fmt("%u", r.numSamples);
|
||||
|
||||
res.variableType.descriptor.name = name;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(dxbc->m_ResourceBinds.find(r.name) != dxbc->m_ResourceBinds.end())
|
||||
{
|
||||
uint32_t vecOffset = 0;
|
||||
res.variableType = MakeShaderVariableType(dxbc->m_ResourceBinds[r.name], vecOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
res.variableType.descriptor.rows = 0;
|
||||
res.variableType.descriptor.cols = 0;
|
||||
res.variableType.descriptor.elements = 0;
|
||||
res.variableType.descriptor.name = "";
|
||||
}
|
||||
}
|
||||
|
||||
res.bindPoint = (int32_t)i;
|
||||
|
||||
BindpointMap map;
|
||||
map.arraySize = r.bindCount == 0 ? ~0U : r.bindCount;
|
||||
map.bindset = r.space;
|
||||
map.bind = r.reg;
|
||||
map.used = true;
|
||||
|
||||
mapping[i] = map;
|
||||
refl[i] = res;
|
||||
}
|
||||
}
|
||||
|
||||
void MakeShaderReflection(DXBC::DXBCFile *dxbc, ShaderReflection *refl,
|
||||
ShaderBindpointMapping *mapping)
|
||||
{
|
||||
@@ -204,7 +300,7 @@ void MakeShaderReflection(DXBC::DXBCFile *dxbc, ShaderReflection *refl,
|
||||
cb.name = dxbc->m_CBuffers[i].name;
|
||||
cb.bufferBacked = true;
|
||||
cb.byteSize = dxbc->m_CBuffers[i].descriptor.byteSize;
|
||||
cb.bindPoint = (uint32_t)i;
|
||||
cb.bindPoint = (int32_t)i;
|
||||
|
||||
BindpointMap map;
|
||||
map.arraySize = 1;
|
||||
@@ -222,143 +318,32 @@ void MakeShaderReflection(DXBC::DXBCFile *dxbc, ShaderReflection *refl,
|
||||
}
|
||||
}
|
||||
|
||||
int numRWResources = 0;
|
||||
int numROResources = 0;
|
||||
|
||||
for(size_t i = 0; i < dxbc->m_Resources.size(); i++)
|
||||
create_array_uninit(mapping->Samplers, dxbc->m_Samplers.size());
|
||||
create_array_uninit(refl->Samplers, dxbc->m_Samplers.size());
|
||||
for(size_t i = 0; i < dxbc->m_Samplers.size(); i++)
|
||||
{
|
||||
const auto &r = dxbc->m_Resources[i];
|
||||
ShaderSampler &s = refl->Samplers[i];
|
||||
|
||||
if(r.type != DXBC::ShaderInputBind::TYPE_CBUFFER)
|
||||
{
|
||||
bool IsReadWrite = (r.type == DXBC::ShaderInputBind::TYPE_UAV_RWTYPED ||
|
||||
r.type == DXBC::ShaderInputBind::TYPE_UAV_RWSTRUCTURED ||
|
||||
r.type == DXBC::ShaderInputBind::TYPE_UAV_RWBYTEADDRESS ||
|
||||
r.type == DXBC::ShaderInputBind::TYPE_UAV_APPEND_STRUCTURED ||
|
||||
r.type == DXBC::ShaderInputBind::TYPE_UAV_CONSUME_STRUCTURED ||
|
||||
r.type == DXBC::ShaderInputBind::TYPE_UAV_RWSTRUCTURED_WITH_COUNTER);
|
||||
|
||||
if(IsReadWrite)
|
||||
numRWResources++;
|
||||
else
|
||||
numROResources++;
|
||||
}
|
||||
}
|
||||
|
||||
create_array_uninit(mapping->ReadWriteResources, numRWResources);
|
||||
create_array_uninit(refl->ReadWriteResources, numRWResources);
|
||||
|
||||
create_array_uninit(mapping->ReadOnlyResources, numROResources);
|
||||
create_array_uninit(refl->ReadOnlyResources, numROResources);
|
||||
|
||||
int32_t rwidx = 0, roidx = 0;
|
||||
for(size_t i = 0; i < dxbc->m_Resources.size(); i++)
|
||||
{
|
||||
const auto &r = dxbc->m_Resources[i];
|
||||
|
||||
if(r.type == DXBC::ShaderInputBind::TYPE_CBUFFER)
|
||||
continue;
|
||||
|
||||
ShaderResource res;
|
||||
res.name = r.name;
|
||||
|
||||
res.IsSampler = (r.type == DXBC::ShaderInputBind::TYPE_SAMPLER);
|
||||
res.IsTexture = (r.type == DXBC::ShaderInputBind::TYPE_TEXTURE &&
|
||||
r.dimension != DXBC::ShaderInputBind::DIM_UNKNOWN &&
|
||||
r.dimension != DXBC::ShaderInputBind::DIM_BUFFER &&
|
||||
r.dimension != DXBC::ShaderInputBind::DIM_BUFFEREX);
|
||||
res.IsReadOnly = (r.type == DXBC::ShaderInputBind::TYPE_TBUFFER ||
|
||||
r.type == DXBC::ShaderInputBind::TYPE_SAMPLER ||
|
||||
r.type == DXBC::ShaderInputBind::TYPE_TEXTURE ||
|
||||
r.type == DXBC::ShaderInputBind::TYPE_STRUCTURED ||
|
||||
r.type == DXBC::ShaderInputBind::TYPE_BYTEADDRESS);
|
||||
|
||||
switch(r.dimension)
|
||||
{
|
||||
default:
|
||||
case DXBC::ShaderInputBind::DIM_UNKNOWN: res.resType = TextureDim::Unknown; break;
|
||||
case DXBC::ShaderInputBind::DIM_BUFFER:
|
||||
case DXBC::ShaderInputBind::DIM_BUFFEREX: res.resType = TextureDim::Buffer; break;
|
||||
case DXBC::ShaderInputBind::DIM_TEXTURE1D: res.resType = TextureDim::Texture1D; break;
|
||||
case DXBC::ShaderInputBind::DIM_TEXTURE1DARRAY:
|
||||
res.resType = TextureDim::Texture1DArray;
|
||||
break;
|
||||
case DXBC::ShaderInputBind::DIM_TEXTURE2D: res.resType = TextureDim::Texture2D; break;
|
||||
case DXBC::ShaderInputBind::DIM_TEXTURE2DARRAY:
|
||||
res.resType = TextureDim::Texture2DArray;
|
||||
break;
|
||||
case DXBC::ShaderInputBind::DIM_TEXTURE2DMS: res.resType = TextureDim::Texture2DMS; break;
|
||||
case DXBC::ShaderInputBind::DIM_TEXTURE2DMSARRAY:
|
||||
res.resType = TextureDim::Texture2DMSArray;
|
||||
break;
|
||||
case DXBC::ShaderInputBind::DIM_TEXTURE3D: res.resType = TextureDim::Texture3D; break;
|
||||
case DXBC::ShaderInputBind::DIM_TEXTURECUBE: res.resType = TextureDim::TextureCube; break;
|
||||
case DXBC::ShaderInputBind::DIM_TEXTURECUBEARRAY:
|
||||
res.resType = TextureDim::TextureCubeArray;
|
||||
break;
|
||||
}
|
||||
|
||||
if(r.retType != DXBC::ShaderInputBind::RETTYPE_UNKNOWN &&
|
||||
r.retType != DXBC::ShaderInputBind::RETTYPE_MIXED &&
|
||||
r.retType != DXBC::ShaderInputBind::RETTYPE_CONTINUED)
|
||||
{
|
||||
res.variableType.descriptor.rows = 1;
|
||||
res.variableType.descriptor.cols = (uint8_t)r.numSamples;
|
||||
res.variableType.descriptor.elements = 1;
|
||||
|
||||
string name;
|
||||
|
||||
switch(r.retType)
|
||||
{
|
||||
case DXBC::ShaderInputBind::RETTYPE_UNORM: name = "unorm float"; break;
|
||||
case DXBC::ShaderInputBind::RETTYPE_SNORM: name = "snorm float"; break;
|
||||
case DXBC::ShaderInputBind::RETTYPE_SINT: name = "int"; break;
|
||||
case DXBC::ShaderInputBind::RETTYPE_UINT: name = "uint"; break;
|
||||
case DXBC::ShaderInputBind::RETTYPE_FLOAT: name = "float"; break;
|
||||
case DXBC::ShaderInputBind::RETTYPE_DOUBLE: name = "double"; break;
|
||||
default: name = "unknown"; break;
|
||||
}
|
||||
|
||||
name += StringFormat::Fmt("%u", r.numSamples);
|
||||
|
||||
res.variableType.descriptor.name = name;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(dxbc->m_ResourceBinds.find(r.name) != dxbc->m_ResourceBinds.end())
|
||||
{
|
||||
uint32_t vecOffset = 0;
|
||||
res.variableType = MakeShaderVariableType(dxbc->m_ResourceBinds[r.name], vecOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
res.variableType.descriptor.rows = 0;
|
||||
res.variableType.descriptor.cols = 0;
|
||||
res.variableType.descriptor.elements = 0;
|
||||
res.variableType.descriptor.name = "";
|
||||
}
|
||||
}
|
||||
|
||||
res.bindPoint = res.IsReadOnly ? roidx : rwidx;
|
||||
s.name = dxbc->m_Samplers[i].name;
|
||||
s.bindPoint = (int32_t)i;
|
||||
|
||||
BindpointMap map;
|
||||
map.arraySize = r.bindCount == 0 ? ~0U : r.bindCount;
|
||||
map.bindset = r.space;
|
||||
map.bind = r.reg;
|
||||
map.arraySize = 1;
|
||||
map.bindset = dxbc->m_Samplers[i].space;
|
||||
map.bind = dxbc->m_Samplers[i].reg;
|
||||
map.used = true;
|
||||
|
||||
if(res.IsReadOnly)
|
||||
{
|
||||
mapping->ReadOnlyResources[roidx] = map;
|
||||
refl->ReadOnlyResources[roidx++] = res;
|
||||
}
|
||||
else
|
||||
{
|
||||
mapping->ReadWriteResources[rwidx] = map;
|
||||
refl->ReadWriteResources[rwidx++] = res;
|
||||
}
|
||||
mapping->Samplers[i] = map;
|
||||
}
|
||||
|
||||
create_array_uninit(mapping->ReadOnlyResources, dxbc->m_SRVs.size());
|
||||
create_array_uninit(refl->ReadOnlyResources, dxbc->m_SRVs.size());
|
||||
MakeResourceList(true, dxbc, dxbc->m_SRVs, mapping->ReadOnlyResources, refl->ReadOnlyResources);
|
||||
|
||||
create_array_uninit(mapping->ReadWriteResources, dxbc->m_UAVs.size());
|
||||
create_array_uninit(refl->ReadWriteResources, dxbc->m_UAVs.size());
|
||||
MakeResourceList(true, dxbc, dxbc->m_UAVs, mapping->ReadWriteResources, refl->ReadWriteResources);
|
||||
|
||||
uint32_t numInterfaces = 0;
|
||||
for(size_t i = 0; i < dxbc->m_Interfaces.variables.size(); i++)
|
||||
numInterfaces = RDCMAX(dxbc->m_Interfaces.variables[i].descriptor.offset + 1, numInterfaces);
|
||||
|
||||
@@ -3901,7 +3901,7 @@ void SPVModule::MakeReflection(ShaderStage stage, const string &entryPoint,
|
||||
vector<SigParameter> inputs;
|
||||
vector<SigParameter> outputs;
|
||||
vector<cblockpair> cblocks;
|
||||
vector<shaderrespair> roresources, rwresources;
|
||||
vector<shaderrespair> samplers, roresources, rwresources;
|
||||
|
||||
// VKTODOLOW filter to only functions/resources used by entryPoint
|
||||
|
||||
@@ -4134,7 +4134,6 @@ void SPVModule::MakeReflection(ShaderStage stage, const string &entryPoint,
|
||||
|
||||
if(ssbo)
|
||||
{
|
||||
res.IsSampler = false;
|
||||
res.IsReadOnly = false;
|
||||
res.IsTexture = false;
|
||||
res.name = cblock.name;
|
||||
@@ -4208,8 +4207,8 @@ void SPVModule::MakeReflection(ShaderStage stage, const string &entryPoint,
|
||||
else if(type->texdim == spv::DimBuffer)
|
||||
res.resType = TextureDim::Buffer;
|
||||
|
||||
res.IsSampler =
|
||||
type->type == SPVTypeData::eSampledImage || type->type == SPVTypeData::eSampler;
|
||||
bool sepSampler = (type->type == SPVTypeData::eSampler);
|
||||
|
||||
res.IsTexture = res.resType != TextureDim::Buffer && type->type != SPVTypeData::eSampler;
|
||||
res.IsReadOnly = true;
|
||||
|
||||
@@ -4300,7 +4299,9 @@ void SPVModule::MakeReflection(ShaderStage stage, const string &entryPoint,
|
||||
// are used
|
||||
RDCASSERT(!bindmap.used || bindmap.bind >= 0);
|
||||
|
||||
if(res.IsReadOnly)
|
||||
if(sepSampler)
|
||||
samplers.push_back(shaderrespair(bindmap, res));
|
||||
else if(res.IsReadOnly)
|
||||
roresources.push_back(shaderrespair(bindmap, res));
|
||||
else
|
||||
rwresources.push_back(shaderrespair(bindmap, res));
|
||||
@@ -4444,12 +4445,16 @@ void SPVModule::MakeReflection(ShaderStage stage, const string &entryPoint,
|
||||
mapping.InputAttributes[reflection.InputSig[i].regIndex] = (int32_t)i;
|
||||
|
||||
std::sort(cblocks.begin(), cblocks.end());
|
||||
std::sort(samplers.begin(), samplers.end());
|
||||
std::sort(roresources.begin(), roresources.end());
|
||||
std::sort(rwresources.begin(), rwresources.end());
|
||||
|
||||
create_array_uninit(mapping.ConstantBlocks, cblocks.size());
|
||||
create_array_uninit(reflection.ConstantBlocks, cblocks.size());
|
||||
|
||||
create_array_uninit(mapping.Samplers, samplers.size());
|
||||
create_array_uninit(reflection.Samplers, samplers.size());
|
||||
|
||||
create_array_uninit(mapping.ReadOnlyResources, roresources.size());
|
||||
create_array_uninit(reflection.ReadOnlyResources, roresources.size());
|
||||
|
||||
@@ -4468,6 +4473,18 @@ void SPVModule::MakeReflection(ShaderStage stage, const string &entryPoint,
|
||||
reflection.ConstantBlocks[i].bindPoint = (int32_t)i;
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < samplers.size(); i++)
|
||||
{
|
||||
mapping.Samplers[i] = samplers[i].map;
|
||||
// fix up any bind points marked with -1. They were sorted to the end
|
||||
// but from here on we want to just be able to index with the bind point
|
||||
// without any special casing.
|
||||
if(mapping.Samplers[i].bind == -1)
|
||||
mapping.Samplers[i].bind = 0;
|
||||
reflection.Samplers[i].name = samplers[i].bindres.name;
|
||||
reflection.Samplers[i].bindPoint = (int32_t)i;
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < roresources.size(); i++)
|
||||
{
|
||||
mapping.ReadOnlyResources[i] = roresources[i].map;
|
||||
|
||||
Reference in New Issue
Block a user