mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-06 01:50:38 +00:00
Factor out near/far derivation into common driver code
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include "driver/dxgi/dxgi_common.h"
|
||||
#include "replay/replay_driver.h"
|
||||
#include "strings/string_utils.h"
|
||||
#include "d3d12_command_list.h"
|
||||
#include "d3d12_command_queue.h"
|
||||
@@ -734,47 +735,12 @@ void D3D12Replay::InitPostVSBuffers(uint32_t eventId)
|
||||
|
||||
for(uint64_t i = 1; numPosComponents == 4 && i < numPrims; i++)
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// derive near/far, assuming a standard perspective matrix
|
||||
//
|
||||
// the transformation from from pre-projection {Z,W} to post-projection {Z,W}
|
||||
// is linear. So we can say Zpost = Zpre*m + c . Here we assume Wpre = 1
|
||||
// and we know Wpost = Zpre from the perspective matrix.
|
||||
// we can then see from the perspective matrix that
|
||||
// m = F/(F-N)
|
||||
// c = -(F*N)/(F-N)
|
||||
//
|
||||
// with re-arranging and substitution, we then get:
|
||||
// N = -c/m
|
||||
// F = c/(1-m)
|
||||
//
|
||||
// so if we can derive m and c then we can determine N and F. We can do this with
|
||||
// two points, and we pick them reasonably distinct on z to reduce floating-point
|
||||
// error
|
||||
|
||||
Vec4f *pos = (Vec4f *)(byteData + i * stride);
|
||||
|
||||
if(fabs(pos->w - pos0->w) > 0.01f && fabs(pos->z - pos0->z) > 0.01f)
|
||||
{
|
||||
Vec2f A(pos0->w, pos0->z);
|
||||
Vec2f B(pos->w, pos->z);
|
||||
|
||||
float m = (B.y - A.y) / (B.x - A.x);
|
||||
float c = B.y - B.x * m;
|
||||
|
||||
if(m == 1.0f || c == 0.0f)
|
||||
continue;
|
||||
|
||||
if(-c / m <= 0.000001f)
|
||||
continue;
|
||||
|
||||
nearp = -c / m;
|
||||
farp = c / (1 - m);
|
||||
|
||||
found = true;
|
||||
DeriveNearFar(*pos, *pos0, nearp, farp, found);
|
||||
|
||||
if(found)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if we didn't find anything, all z's and w's were identical.
|
||||
@@ -1324,47 +1290,12 @@ void D3D12Replay::InitPostVSBuffers(uint32_t eventId)
|
||||
|
||||
for(UINT64 i = 1; numPosComponents == 4 && i < numVerts; i++)
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// derive near/far, assuming a standard perspective matrix
|
||||
//
|
||||
// the transformation from from pre-projection {Z,W} to post-projection {Z,W}
|
||||
// is linear. So we can say Zpost = Zpre*m + c . Here we assume Wpre = 1
|
||||
// and we know Wpost = Zpre from the perspective matrix.
|
||||
// we can then see from the perspective matrix that
|
||||
// m = F/(F-N)
|
||||
// c = -(F*N)/(F-N)
|
||||
//
|
||||
// with re-arranging and substitution, we then get:
|
||||
// N = -c/m
|
||||
// F = c/(1-m)
|
||||
//
|
||||
// so if we can derive m and c then we can determine N and F. We can do this with
|
||||
// two points, and we pick them reasonably distinct on z to reduce floating-point
|
||||
// error
|
||||
|
||||
Vec4f *pos = (Vec4f *)(byteData + i * stride);
|
||||
|
||||
if(fabs(pos->w - pos0->w) > 0.01f && fabs(pos->z - pos0->z) > 0.01f)
|
||||
{
|
||||
Vec2f A(pos0->w, pos0->z);
|
||||
Vec2f B(pos->w, pos->z);
|
||||
|
||||
float m = (B.y - A.y) / (B.x - A.x);
|
||||
float c = B.y - B.x * m;
|
||||
|
||||
if(m == 1.0f || c == 0.0f)
|
||||
continue;
|
||||
|
||||
if(-c / m <= 0.000001f)
|
||||
continue;
|
||||
|
||||
nearp = -c / m;
|
||||
farp = c / (1 - m);
|
||||
|
||||
found = true;
|
||||
DeriveNearFar(*pos, *pos0, nearp, farp, found);
|
||||
|
||||
if(found)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if we didn't find anything, all z's and w's were identical.
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "core/settings.h"
|
||||
#include "driver/shaders/spirv/spirv_editor.h"
|
||||
#include "driver/shaders/spirv/spirv_op_helpers.h"
|
||||
#include "replay/replay_driver.h"
|
||||
#include "vk_core.h"
|
||||
#include "vk_debug.h"
|
||||
#include "vk_replay.h"
|
||||
@@ -2811,50 +2812,14 @@ void VulkanReplay::FetchVSOut(uint32_t eventId, VulkanRenderState &state)
|
||||
// and position is the first value
|
||||
|
||||
for(uint32_t i = 1;
|
||||
refl->outputSignature[0].systemValue == ShaderBuiltin::Position && i < numVerts; i++)
|
||||
refl->outputSignature[0].systemValue == ShaderBuiltin::Position && !found && i < numVerts; i++)
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// derive near/far, assuming a standard perspective matrix
|
||||
//
|
||||
// the transformation from from pre-projection {Z,W} to post-projection {Z,W}
|
||||
// is linear. So we can say Zpost = Zpre*m + c . Here we assume Wpre = 1
|
||||
// and we know Wpost = Zpre from the perspective matrix.
|
||||
// we can then see from the perspective matrix that
|
||||
// m = F/(F-N)
|
||||
// c = -(F*N)/(F-N)
|
||||
//
|
||||
// with re-arranging and substitution, we then get:
|
||||
// N = -c/m
|
||||
// F = c/(1-m)
|
||||
//
|
||||
// so if we can derive m and c then we can determine N and F. We can do this with
|
||||
// two points, and we pick them reasonably distinct on z to reduce floating-point
|
||||
// error
|
||||
|
||||
Vec4f *pos = (Vec4f *)(byteData + i * bufStride);
|
||||
|
||||
// skip invalid vertices (w=0)
|
||||
if(pos->w != 0.0f && fabs(pos->w - pos0->w) > 0.01f && fabs(pos->z - pos0->z) > 0.01f)
|
||||
{
|
||||
Vec2f A(pos0->w, pos0->z);
|
||||
Vec2f B(pos->w, pos->z);
|
||||
|
||||
float m = (B.y - A.y) / (B.x - A.x);
|
||||
float c = B.y - B.x * m;
|
||||
|
||||
if(m == 1.0f || c == 0.0f)
|
||||
continue;
|
||||
|
||||
if(-c / m <= 0.000001f)
|
||||
continue;
|
||||
|
||||
nearp = -c / m;
|
||||
farp = c / (1 - m);
|
||||
|
||||
found = true;
|
||||
DeriveNearFar(*pos, *pos0, nearp, farp, found);
|
||||
|
||||
if(found)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if we didn't find anything, all z's and w's were identical.
|
||||
@@ -3408,50 +3373,10 @@ void VulkanReplay::FetchTessGSOut(uint32_t eventId, VulkanRenderState &state)
|
||||
if(readbackoffset == 0)
|
||||
memcpy(&pos0, data.data(), sizeof(pos0));
|
||||
|
||||
for(uint32_t i = 0; i < data.size() / xfbStride; i++)
|
||||
for(uint32_t i = 0; !found && i < data.size() / xfbStride; i++)
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// derive near/far, assuming a standard perspective matrix
|
||||
//
|
||||
// the transformation from from pre-projection {Z,W} to post-projection {Z,W}
|
||||
// is linear. So we can say Zpost = Zpre*m + c . Here we assume Wpre = 1
|
||||
// and we know Wpost = Zpre from the perspective matrix.
|
||||
// we can then see from the perspective matrix that
|
||||
// m = F/(F-N)
|
||||
// c = -(F*N)/(F-N)
|
||||
//
|
||||
// with re-arranging and substitution, we then get:
|
||||
// N = -c/m
|
||||
// F = c/(1-m)
|
||||
//
|
||||
// so if we can derive m and c then we can determine N and F. We can do this with
|
||||
// two points, and we pick them reasonably distinct on z to reduce floating-point
|
||||
// error
|
||||
|
||||
Vec4f *pos = (Vec4f *)(data.data() + xfbStride * i);
|
||||
|
||||
// skip invalid vertices (w=0)
|
||||
if(pos->w != 0.0f && fabs(pos->w - pos0.w) > 0.01f && fabs(pos->z - pos0.z) > 0.01f)
|
||||
{
|
||||
Vec2f A(pos0.w, pos0.z);
|
||||
Vec2f B(pos->w, pos->z);
|
||||
|
||||
float m = (B.y - A.y) / (B.x - A.x);
|
||||
float c = B.y - B.x * m;
|
||||
|
||||
if(m == 1.0f || c == 0.0f)
|
||||
continue;
|
||||
|
||||
if(-c / m <= 0.000001f)
|
||||
continue;
|
||||
|
||||
nearp = -c / m;
|
||||
farp = c / (1 - m);
|
||||
|
||||
found = true;
|
||||
|
||||
break;
|
||||
}
|
||||
DeriveNearFar(*pos, pos0, nearp, farp, found);
|
||||
}
|
||||
|
||||
if(found)
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
******************************************************************************/
|
||||
|
||||
#include "replay_driver.h"
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
#include "compressonator/CMP_Core.h"
|
||||
#include "maths/formatpacking.h"
|
||||
#include "maths/half_convert.h"
|
||||
@@ -1802,3 +1804,45 @@ bytebuf GetDiscardPattern(DiscardType type, const ResourceFormat &fmt, uint32_t
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void DeriveNearFar(Vec4f pos, Vec4f pos0, float &nearp, float &farp, bool &found)
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// derive near/far, assuming a standard perspective matrix
|
||||
//
|
||||
// the transformation from from pre-projection {Z,W} to post-projection {Z,W}
|
||||
// is linear. So we can say Zpost = Zpre*m + c . Here we assume Wpre = 1
|
||||
// and we know Wpost = Zpre from the perspective matrix.
|
||||
// we can then see from the perspective matrix that
|
||||
// m = F/(F-N)
|
||||
// c = -(F*N)/(F-N)
|
||||
//
|
||||
// with re-arranging and substitution, we then get:
|
||||
// N = -c/m
|
||||
// F = c/(1-m)
|
||||
//
|
||||
// so if we can derive m and c then we can determine N and F. We can do this with
|
||||
// two points, and we pick them reasonably distinct on z to reduce floating-point
|
||||
// error
|
||||
|
||||
// skip invalid vertices (w=0)
|
||||
if(pos.w != 0.0f && fabsf(pos.w - pos0.w) > 0.01f && fabsf(pos.z - pos0.z) > 0.01f)
|
||||
{
|
||||
Vec2f A(pos0.w, pos0.z);
|
||||
Vec2f B(pos.w, pos.z);
|
||||
|
||||
float m = (B.y - A.y) / (B.x - A.x);
|
||||
float c = B.y - B.x * m;
|
||||
|
||||
if(m == 1.0f || c == 0.0f)
|
||||
return;
|
||||
|
||||
if(-c / m <= 0.000001f)
|
||||
return;
|
||||
|
||||
nearp = -c / m;
|
||||
farp = c / (1 - m);
|
||||
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -369,3 +369,5 @@ static constexpr uint32_t DiscardPatternHeight = 8;
|
||||
// returns a pattern to fill the texture with
|
||||
bytebuf GetDiscardPattern(DiscardType type, const ResourceFormat &fmt, uint32_t rowPitch = 1,
|
||||
bool invert = false);
|
||||
|
||||
void DeriveNearFar(Vec4f pos, Vec4f pos0, float &nearp, float &farp, bool &found);
|
||||
|
||||
Reference in New Issue
Block a user