diff --git a/qrenderdoc/Windows/BufferViewer.cpp b/qrenderdoc/Windows/BufferViewer.cpp index 9caf54bb1..cd4905513 100644 --- a/qrenderdoc/Windows/BufferViewer.cpp +++ b/qrenderdoc/Windows/BufferViewer.cpp @@ -455,6 +455,7 @@ struct BufferElementProperties int buffer = 0; ShaderBuiltin systemValue = ShaderBuiltin::Undefined; bool perinstance = false; + bool floatCastWrong = false; int instancerate = 1; }; @@ -733,7 +734,14 @@ static QString interpretVariant(const QVariant &v, const ShaderConstant &el, } else if(vt == QMetaType::UInt || vt == QMetaType::UShort || vt == QMetaType::UChar) { - uint u = v.toUInt(); + uint32_t u = v.toUInt(); + + if(prop.floatCastWrong) + { + float f = (float)u; + memcpy(&u, &f, sizeof(f)); + } + if(el.type.descriptor.displayAsHex && prop.format.type == ResourceFormatType::Regular) ret = Formatter::HexFormat(u, prop.format.compByteWidth); else @@ -741,7 +749,14 @@ static QString interpretVariant(const QVariant &v, const ShaderConstant &el, } else if(vt == QMetaType::Int || vt == QMetaType::Short || vt == QMetaType::SChar) { - int i = v.toInt(); + int32_t i = v.toInt(); + + if(prop.floatCastWrong) + { + float f = (float)i; + memcpy(&i, &f, sizeof(f)); + } + if(i >= 0) ret = lit(" ") + Formatter::Format(i); else @@ -1533,6 +1548,7 @@ static void ConfigureMeshColumns(ICaptureContext &ctx, PopulateBufferData *bufda p.buffer = a.vertexBuffer; p.perinstance = a.perInstance; p.instancerate = a.instanceRate; + p.floatCastWrong = a.floatCastWrong; p.format = a.format; bufdata->vsinConfig.genericsEnabled[bufdata->vsinConfig.columns.count()] = false; diff --git a/renderdoc/api/replay/common_pipestate.h b/renderdoc/api/replay/common_pipestate.h index 1cb58d347..7ab1271f0 100644 --- a/renderdoc/api/replay/common_pipestate.h +++ b/renderdoc/api/replay/common_pipestate.h @@ -482,6 +482,16 @@ from the vertex buffer before advancing to the next value. PixelValue genericValue; DOCUMENT("``True`` if this attribute is using :data:`genericValue` for its data."); bool genericEnabled = false; + DOCUMENT(R"(Only valid for attributes on OpenGL. If the attribute has been set up for integers to +be converted to floats (glVertexAttribFormat with GL_INT) we store the format as integers. This is +fine if the application has a float input in the shader it just means we display the raw integer +instead of the casted float. However if the shader has an integer input this is invalid and it will +read something undefined - possibly the int bits of the casted float. + +This property is set to ``True`` if the cast happens to an integer input and that bad cast needs to +be emulated. +)"); + bool floatCastWrong = false; DOCUMENT("``True`` if this attribute is enabled and used by the vertex shader."); bool used; }; diff --git a/renderdoc/api/replay/pipestate.inl b/renderdoc/api/replay/pipestate.inl index 5d58e321d..8d145a3de 100644 --- a/renderdoc/api/replay/pipestate.inl +++ b/renderdoc/api/replay/pipestate.inl @@ -800,16 +800,23 @@ rdcarray PipeState::GetVertexInputs() const { int attrib = m_GL->vertexShader.bindpointMapping.inputAttributes[i]; + const SigParameter &sigParam = m_GL->vertexShader.reflection->inputSignature[attrib]; + if(attrib >= 0 && attrib < m_GL->vertexShader.reflection->inputSignature.count()) - ret[a].name = m_GL->vertexShader.reflection->inputSignature[attrib].varName; + ret[a].name = sigParam.varName; if(attrib == -1) continue; + VarType varType = sigParam.varType; + + if(attrs[i].floatCast && (VarTypeCompType(sigParam.varType) == CompType::UInt || + VarTypeCompType(sigParam.varType) == CompType::SInt)) + ret[a].floatCastWrong = true; + if(!attrs[i].enabled) { - uint32_t compCount = m_GL->vertexShader.reflection->inputSignature[attrib].compCount; - VarType varType = m_GL->vertexShader.reflection->inputSignature[attrib].varType; + uint32_t compCount = sigParam.compCount; for(uint32_t c = 0; c < compCount; c++) {