mirror of
https://github.com/Inori/GPCS4.git
synced 2024-06-02 19:38:19 -04:00
fix depth clear state
This commit is contained in:
parent
7983c75018
commit
50e675247b
|
@ -11,7 +11,7 @@ using namespace sce::Gnm;
|
|||
|
||||
namespace sce::gcn
|
||||
{
|
||||
GcnBinaryInfo::GcnBinaryInfo(const uint8_t* shaderCode)
|
||||
GcnBinaryInfo::GcnBinaryInfo(const void* shaderCode)
|
||||
{
|
||||
const uint32_t* token = reinterpret_cast<const uint32_t*>(shaderCode);
|
||||
const uint32_t tokenMovVccHi = 0xBEEB03FF;
|
||||
|
@ -29,6 +29,40 @@ namespace sce::gcn
|
|||
{
|
||||
}
|
||||
|
||||
VkShaderStageFlagBits GcnBinaryInfo::stage() const
|
||||
{
|
||||
VkShaderStageFlagBits result = VK_SHADER_STAGE_FLAG_BITS_MAX_ENUM;
|
||||
ShaderBinaryType binType = static_cast<ShaderBinaryType>(m_binInfo->m_type);
|
||||
switch (binType)
|
||||
{
|
||||
case ShaderBinaryType::kPixelShader:
|
||||
result = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
break;
|
||||
case ShaderBinaryType::kVertexShader:
|
||||
result = VK_SHADER_STAGE_VERTEX_BIT;
|
||||
break;
|
||||
case ShaderBinaryType::kComputeShader:
|
||||
result = VK_SHADER_STAGE_COMPUTE_BIT;
|
||||
break;
|
||||
case ShaderBinaryType::kGeometryShader:
|
||||
result = VK_SHADER_STAGE_GEOMETRY_BIT;
|
||||
break;
|
||||
case ShaderBinaryType::kHullShader:
|
||||
result = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
|
||||
break;
|
||||
case ShaderBinaryType::kDomainShader:
|
||||
result = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
|
||||
break;
|
||||
case ShaderBinaryType::kLocalShader:
|
||||
case ShaderBinaryType::kExportShader:
|
||||
case ShaderBinaryType::kUnknown:
|
||||
default:
|
||||
LOG_ASSERT(false, "unknown shader stage.");
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
GcnHeader::GcnHeader(const uint8_t* shaderCode)
|
||||
{
|
||||
parseHeader(shaderCode);
|
||||
|
@ -41,7 +75,7 @@ namespace sce::gcn
|
|||
|
||||
GcnProgramType GcnHeader::type() const
|
||||
{
|
||||
GcnProgramType result;
|
||||
GcnProgramType result = GcnProgramType::VertexShader;
|
||||
ShaderBinaryType binType = static_cast<ShaderBinaryType>(m_binInfo.m_type);
|
||||
switch (binType)
|
||||
{
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
namespace sce::gcn
|
||||
{
|
||||
enum class GcnProgramType;
|
||||
enum class GcnProgramType : uint16_t;
|
||||
|
||||
/**
|
||||
* \brief Represent a resource bound to a GCN shader
|
||||
|
@ -47,7 +47,7 @@ namespace sce::gcn
|
|||
{
|
||||
public:
|
||||
GcnBinaryInfo(
|
||||
const uint8_t* shaderCode);
|
||||
const void* shaderCode);
|
||||
~GcnBinaryInfo();
|
||||
|
||||
/**
|
||||
|
@ -73,6 +73,11 @@ namespace sce::gcn
|
|||
m_binInfo->m_shaderHash0, m_binInfo->m_crc32);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Shader stage
|
||||
*/
|
||||
VkShaderStageFlagBits stage() const;
|
||||
|
||||
/**
|
||||
* \brief Information of shader binary
|
||||
*/
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace sce::gcn
|
|||
kUnknown = 6,
|
||||
kHullShader = 7, ///< HS stage shader.
|
||||
kDomainShader = 8, ///< DS stage shader with embedded CS stage frontend shader.
|
||||
} ShaderType;
|
||||
};
|
||||
|
||||
struct ShaderBinaryInfo
|
||||
{
|
||||
|
|
|
@ -299,10 +299,9 @@ namespace sce::Gnm
|
|||
|
||||
void GnmCommandBuffer::commitComputeState(GnmShaderContext& ctx)
|
||||
{
|
||||
GcnModule csModule(
|
||||
reinterpret_cast<const uint8_t*>(ctx.code));
|
||||
auto shader = getShader(ctx.code, ctx.meta);
|
||||
|
||||
auto& resTable = csModule.getResourceTable();
|
||||
auto& resTable = shader.getResources();
|
||||
|
||||
// create and bind shader resources
|
||||
bindResource(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, resTable, ctx.userData);
|
||||
|
@ -310,7 +309,7 @@ namespace sce::Gnm
|
|||
// bind the shader
|
||||
m_context->bindShader(
|
||||
VK_SHADER_STAGE_COMPUTE_BIT,
|
||||
csModule.compile(ctx.meta, m_moduleInfo));
|
||||
shader.handle());
|
||||
}
|
||||
|
||||
ShaderStage GnmCommandBuffer::getShaderStage(
|
||||
|
@ -437,4 +436,13 @@ namespace sce::Gnm
|
|||
{
|
||||
}
|
||||
|
||||
GnmShader GnmCommandBuffer::getShader(
|
||||
const void* code, GcnShaderMeta& meta)
|
||||
{
|
||||
GcnBinaryInfo info(code);
|
||||
VltShaderKey key(info.stage(), info.key());
|
||||
return m_shaderModules.getShaderModule(
|
||||
&key, &m_moduleInfo, meta, code);
|
||||
}
|
||||
|
||||
} // namespace sce::Gnm
|
|
@ -8,6 +8,7 @@
|
|||
#include "GnmResourceFactory.h"
|
||||
#include "GnmInitializer.h"
|
||||
#include "GnmRenderState.h"
|
||||
#include "GnmShader.h"
|
||||
#include "Violet/VltRc.h"
|
||||
#include "Gcn/GcnShaderMeta.h"
|
||||
#include "Gcn/GcnHeader.h"
|
||||
|
@ -492,6 +493,10 @@ namespace sce::Gnm
|
|||
gcn::GcnTextureMeta populateTextureMeta(
|
||||
const Texture* tsharp, bool isDepth);
|
||||
|
||||
GnmShader getShader(
|
||||
const void* code,
|
||||
gcn::GcnShaderMeta& meta);
|
||||
|
||||
private:
|
||||
void initGcnModuleInfo();
|
||||
|
||||
|
|
|
@ -3,13 +3,14 @@
|
|||
#include "GnmBuffer.h"
|
||||
#include "GnmConverter.h"
|
||||
#include "GnmGpuLabel.h"
|
||||
#include "GnmLabelManager.h"
|
||||
#include "GnmSampler.h"
|
||||
#include "GnmShader.h"
|
||||
#include "GnmSharpBuffer.h"
|
||||
#include "GnmTexture.h"
|
||||
#include "GnmLabelManager.h"
|
||||
#include "GnmShader.h"
|
||||
#include "GpuAddress/GnmGpuAddress.h"
|
||||
|
||||
#include "Gcn/GcnHeader.h"
|
||||
#include "Gcn/GcnUtil.h"
|
||||
#include "Platform/PlatFile.h"
|
||||
#include "Sce/SceGpuQueue.h"
|
||||
|
@ -129,7 +130,7 @@ namespace sce::Gnm
|
|||
viewport.height != vp.height ||
|
||||
viewport.minDepth != vp.minDepth ||
|
||||
viewport.maxDepth != vp.maxDepth;
|
||||
|
||||
|
||||
if (dirty)
|
||||
{
|
||||
m_state.gp.rs.viewports[viewportId] = viewport;
|
||||
|
@ -308,7 +309,7 @@ namespace sce::Gnm
|
|||
{
|
||||
Rc<VltImageView> targetView = nullptr;
|
||||
|
||||
do
|
||||
do
|
||||
{
|
||||
if (target == nullptr)
|
||||
{
|
||||
|
@ -369,7 +370,7 @@ namespace sce::Gnm
|
|||
|
||||
auto zBufferAddr = depthTarget->getZReadAddress();
|
||||
auto resource = m_tracker.find(zBufferAddr);
|
||||
|
||||
|
||||
if (!resource)
|
||||
{
|
||||
// create a new depth image and track it
|
||||
|
@ -413,16 +414,20 @@ namespace sce::Gnm
|
|||
|
||||
void GnmCommandBufferDraw::setDepthClearValue(float clearValue)
|
||||
{
|
||||
VkClearValue value;
|
||||
value.depthStencil.depth = clearValue;
|
||||
m_context->setDepthClearValue(value);
|
||||
if (m_state.gp.om.dsClear.depthValue.depthStencil.depth != clearValue)
|
||||
{
|
||||
m_state.gp.om.dsClear.depthValue.depthStencil.depth = clearValue;
|
||||
m_flags.set(GnmContextFlag::DirtyDepthStencilClear);
|
||||
}
|
||||
}
|
||||
|
||||
void GnmCommandBufferDraw::setStencilClearValue(uint8_t clearValue)
|
||||
{
|
||||
VkClearValue value;
|
||||
value.depthStencil.stencil = clearValue;
|
||||
m_context->setStencilClearValue(value);
|
||||
if (m_state.gp.om.dsClear.stencilValue.depthStencil.stencil != clearValue)
|
||||
{
|
||||
m_state.gp.om.dsClear.stencilValue.depthStencil.stencil = clearValue;
|
||||
m_flags.set(GnmContextFlag::DirtyDepthStencilClear);
|
||||
}
|
||||
}
|
||||
|
||||
void GnmCommandBufferDraw::setRenderTargetMask(uint32_t mask)
|
||||
|
@ -497,6 +502,11 @@ namespace sce::Gnm
|
|||
ds.stencilOpFront.compareOp != stencilFront ||
|
||||
ds.stencilOpBack.compareOp != stencilBack;
|
||||
|
||||
// In vulkan, depth write can only be enabled,
|
||||
// when depth test is also enabled.
|
||||
// If depth test is disabled then depth writes are also disabled,
|
||||
// regardless of the value of
|
||||
// VkPipelineDepthStencilStateCreateInfo::depthWriteEnable
|
||||
if (dirty)
|
||||
{
|
||||
ds.enableDepthTest = depthControl.depthEnable;
|
||||
|
@ -511,36 +521,36 @@ namespace sce::Gnm
|
|||
|
||||
void GnmCommandBufferDraw::setDbRenderControl(DbRenderControl reg)
|
||||
{
|
||||
//bool depthClear = reg.getDepthClearEnable();
|
||||
//bool htielCompress = reg.getHtileResummarizeEnable();
|
||||
//if (depthClear && !htielCompress)
|
||||
//{
|
||||
// // In Gnm, when depth clear enable and HTILE compress disable
|
||||
// // all writes to the depth buffer will use the depth clear value set by
|
||||
// // DrawCommandBuffer::setDepthClearValue() instead of the fragment's depth value.
|
||||
// //
|
||||
// // For vulkan, we use depth bound test to emulate this somehow.
|
||||
// // We first set the depth clear value to clear depth buffer once render pass begin.
|
||||
// // Then force depth bound test failed to leave depth buffer untouched.
|
||||
// // This way the depth buffer remains the clear value.
|
||||
bool depthClear = reg.getDepthClearEnable();
|
||||
bool htielCompress = reg.getHtileResummarizeEnable();
|
||||
VkBool32 depthWrite = VK_TRUE;
|
||||
if (depthClear && !htielCompress)
|
||||
{
|
||||
// In Gnm, when depth clear enable and HTILE compress disable
|
||||
// all writes to the depth buffer will use the depth clear value set by
|
||||
// DrawCommandBuffer::setDepthClearValue() instead of the fragment's depth value.
|
||||
//
|
||||
// For vulkan, we set depth clear value and LOAD_OP_CLEAR when render pass begin,
|
||||
// then disable depth write so that depth buffer keeps the clear value.
|
||||
depthWrite = VK_FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
depthWrite = VK_TRUE;
|
||||
}
|
||||
|
||||
// // TODO:
|
||||
// // This approach is not accurate, fix it in the future.
|
||||
if (m_state.gp.om.dsState.enableDepthWrite != depthWrite)
|
||||
{
|
||||
m_state.gp.om.dsState.enableDepthWrite = depthWrite;
|
||||
m_flags.set(GnmContextFlag::DirtyDepthStencilState);
|
||||
}
|
||||
|
||||
// m_context->setDepthBoundsTestEnable(VK_TRUE);
|
||||
|
||||
// VltDepthBoundsRange depthBounds;
|
||||
// depthBounds.minDepthBounds = 1.0;
|
||||
// depthBounds.maxDepthBounds = 0.0;
|
||||
// m_context->setDepthBoundsRange(depthBounds);
|
||||
|
||||
// m_state.ds.dbClearDepth = true;
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// m_context->setDepthBoundsTestEnable(VK_FALSE);
|
||||
// m_state.ds.dbClearDepth = false;
|
||||
//}
|
||||
bool clearDepth = (!depthWrite);
|
||||
if (m_state.gp.om.dsClear.enableDepthClear != clearDepth)
|
||||
{
|
||||
m_state.gp.om.dsClear.enableDepthClear = clearDepth;
|
||||
m_flags.set(GnmContextFlag::DirtyDepthStencilClear);
|
||||
}
|
||||
}
|
||||
|
||||
void GnmCommandBufferDraw::setVgtControl(uint8_t primGroupSizeMinusOne)
|
||||
|
@ -707,11 +717,10 @@ namespace sce::Gnm
|
|||
// or should we create a new render target image and then bilt to swapchain like DXVK does?
|
||||
|
||||
// get render target from swapchain
|
||||
auto& tracker = GPU().resourceTracker();
|
||||
auto& videoOut = GPU().videoOutGet(videoOutHandle);
|
||||
auto dispBuffer = videoOut.getDisplayBuffer(displayBufferIndex);
|
||||
|
||||
auto res = tracker.find(dispBuffer.address);
|
||||
auto res = m_tracker.find(dispBuffer.address);
|
||||
if (res)
|
||||
{
|
||||
auto& image = res->renderTarget().image;
|
||||
|
@ -973,13 +982,12 @@ namespace sce::Gnm
|
|||
VltBufferSlice(indexBuffer, 0, indexBuffer->info().size),
|
||||
m_state.gp.ia.indexType);
|
||||
|
||||
GcnModule vsModule(
|
||||
reinterpret_cast<const uint8_t*>(ctx.code));
|
||||
auto shader = getShader(ctx.code, ctx.meta);
|
||||
|
||||
auto& resTable = vsModule.getResourceTable();
|
||||
auto& resTable = shader.getResources();
|
||||
|
||||
//// Update input layout and bind vertex buffer
|
||||
updateVertexBinding(vsModule);
|
||||
updateVertexBinding(shader);
|
||||
|
||||
//// create and bind shader resources
|
||||
bindResource(VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, resTable, ctx.userData);
|
||||
|
@ -987,7 +995,7 @@ namespace sce::Gnm
|
|||
// bind the shader
|
||||
m_context->bindShader(
|
||||
VK_SHADER_STAGE_VERTEX_BIT,
|
||||
vsModule.compile(ctx.meta, m_moduleInfo));
|
||||
shader.handle());
|
||||
} while (false);
|
||||
}
|
||||
|
||||
|
@ -1002,10 +1010,9 @@ namespace sce::Gnm
|
|||
break;
|
||||
}
|
||||
|
||||
GcnModule psModule(
|
||||
reinterpret_cast<const uint8_t*>(ctx.code));
|
||||
auto shader = getShader(ctx.code, ctx.meta);
|
||||
|
||||
auto& resTable = psModule.getResourceTable();
|
||||
auto& resTable = shader.getResources();
|
||||
|
||||
// create and bind shader resources
|
||||
bindResource(VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, resTable, ctx.userData);
|
||||
|
@ -1013,7 +1020,7 @@ namespace sce::Gnm
|
|||
// bind the shader
|
||||
m_context->bindShader(
|
||||
VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
psModule.compile(ctx.meta, m_moduleInfo));
|
||||
shader.handle());
|
||||
} while (false);
|
||||
}
|
||||
|
||||
|
@ -1236,7 +1243,7 @@ namespace sce::Gnm
|
|||
void GnmCommandBufferDraw::applyViewportState()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void GnmCommandBufferDraw::initDefaultRenderState()
|
||||
{
|
||||
m_state.gp.sc = {};
|
||||
|
|
|
@ -156,20 +156,6 @@ namespace sce::Gnm
|
|||
virtual void popMarker() override;
|
||||
|
||||
private:
|
||||
const void* findFetchShader(
|
||||
const gcn::GcnShaderResourceTable& table,
|
||||
const UserDataSlot& userData);
|
||||
|
||||
bool isSingleVertexBinding(
|
||||
const uint32_t* vtxTable,
|
||||
const gcn::VertexInputSemanticTable& semanticTable);
|
||||
|
||||
vlt::Rc<vlt::VltBuffer> generateIndexBuffer(
|
||||
const void* data,
|
||||
uint32_t size);
|
||||
|
||||
vlt::Rc<vlt::VltBuffer> generateIndexBufferAuto(
|
||||
uint32_t indexCount);
|
||||
|
||||
inline void bindVertexBuffer(
|
||||
const Buffer* vsharp, uint32_t binding);
|
||||
|
@ -229,6 +215,21 @@ namespace sce::Gnm
|
|||
vlt::VltLogicOpState* loState,
|
||||
vlt::VltMultisampleState* msState);
|
||||
|
||||
const void* findFetchShader(
|
||||
const gcn::GcnShaderResourceTable& table,
|
||||
const UserDataSlot& userData);
|
||||
|
||||
bool isSingleVertexBinding(
|
||||
const uint32_t* vtxTable,
|
||||
const gcn::VertexInputSemanticTable& semanticTable);
|
||||
|
||||
vlt::Rc<vlt::VltBuffer> generateIndexBuffer(
|
||||
const void* data,
|
||||
uint32_t size);
|
||||
|
||||
vlt::Rc<vlt::VltBuffer> generateIndexBufferAuto(
|
||||
uint32_t indexCount);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "GnmCommandBufferDummy.h"
|
||||
#include "PlatProcess.h"
|
||||
#include "Violet/VltBuffer.h"
|
||||
#include "Violet/VltImage.h"
|
||||
|
||||
namespace sce::Gnm
|
||||
{
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "Gcn/GcnShaderRegister.h"
|
||||
#include "Violet/VltBuffer.h"
|
||||
#include "Violet/VltImage.h"
|
||||
|
||||
using namespace util;
|
||||
using namespace sce::vlt;
|
||||
|
|
|
@ -41,6 +41,7 @@ namespace sce::Gnm
|
|||
DirtyRenderTargets,
|
||||
DirtyBlendState,
|
||||
DirtyDepthStencilState,
|
||||
DirtyDepthStencilClear,
|
||||
};
|
||||
|
||||
using GnmContextFlags = util::Flags<GnmContextFlag>;
|
||||
|
@ -72,11 +73,12 @@ namespace sce::Gnm
|
|||
|
||||
struct GnmOutputMergerState
|
||||
{
|
||||
vlt::VltRenderTargets renderTargets;
|
||||
vlt::VltDepthStencilState dsState;
|
||||
vlt::VltMultisampleState msState;
|
||||
vlt::VltLogicOpState loState;
|
||||
std::array<VltBlendMode, 8> blendModes;
|
||||
vlt::VltRenderTargets renderTargets;
|
||||
vlt::VltDepthStencilState dsState;
|
||||
vlt::VltMultisampleState msState;
|
||||
vlt::VltLogicOpState loState;
|
||||
vlt::VltDepthStencilClear dsClear;
|
||||
std::array<vlt::VltBlendMode, 8> blendModes;
|
||||
|
||||
float blendFactor[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
uint32_t sampleMask = 0xFFFFFFFFu;
|
||||
|
|
|
@ -78,7 +78,7 @@ namespace sce::Gnm
|
|||
}
|
||||
}
|
||||
|
||||
return std::move(shader);
|
||||
return shader;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -4,16 +4,12 @@
|
|||
#include "Gcn/GcnModInfo.h"
|
||||
#include "Gcn/GcnHeader.h"
|
||||
#include "Gcn/GcnShaderMeta.h"
|
||||
#include "Violet/VltShaderKey.h"
|
||||
#include "Violet/VltShader.h"
|
||||
|
||||
#include <array>
|
||||
#include <mutex>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace sce::vlt
|
||||
{
|
||||
class VltShader;
|
||||
} // namespace sce::vlt
|
||||
|
||||
|
||||
namespace sce::Gnm
|
||||
|
@ -35,7 +31,7 @@ namespace sce::Gnm
|
|||
const void* code);
|
||||
~GnmShader();
|
||||
|
||||
vlt::Rc<vlt::VltShader> getShader() const
|
||||
vlt::Rc<vlt::VltShader> handle() const
|
||||
{
|
||||
return m_shader;
|
||||
}
|
||||
|
|
|
@ -239,6 +239,7 @@ namespace sce
|
|||
|
||||
uint32_t vqueueIndex = vqueueId - VQueueIdBegin;
|
||||
m_computeQueues[vqueueIndex] = std::make_unique<SceComputeQueue>(m_device.ptr(),
|
||||
*m_objects,
|
||||
ringBaseAddr,
|
||||
ringSizeInDW,
|
||||
readPtrAddr);
|
||||
|
@ -286,7 +287,7 @@ namespace sce
|
|||
|
||||
void SceGnmDriver::trackRenderTarget(uint32_t index)
|
||||
{
|
||||
auto& tracker = GPU().resourceTracker();
|
||||
auto& tracker = m_objects->resourceTracker();
|
||||
|
||||
auto& renderTarget = m_swapchain->getImage(index);
|
||||
|
||||
|
@ -297,10 +298,10 @@ namespace sce
|
|||
{
|
||||
// Reset global objects.
|
||||
|
||||
auto& tracker = GPU().resourceTracker();
|
||||
auto& tracker = m_objects->resourceTracker();
|
||||
tracker.reset();
|
||||
|
||||
auto& labelMgr = GPU().labelManager();
|
||||
auto& labelMgr = m_objects->labelManager();
|
||||
labelMgr.reset();
|
||||
}
|
||||
|
||||
|
@ -323,7 +324,7 @@ namespace sce
|
|||
//
|
||||
// This need to be optimized a lot.
|
||||
|
||||
auto& tracker = GPU().resourceTracker();
|
||||
auto& tracker = m_objects->resourceTracker();
|
||||
|
||||
auto context = m_device->createContext();
|
||||
context->beginRecording(
|
||||
|
|
|
@ -19,7 +19,7 @@ namespace sce
|
|||
SceObjects& objects) :
|
||||
m_device(device)
|
||||
{
|
||||
createQueue(type);
|
||||
createQueue(type, objects);
|
||||
}
|
||||
|
||||
SceGpuQueue::~SceGpuQueue()
|
||||
|
@ -51,15 +51,15 @@ namespace sce
|
|||
|
||||
if (type == SceQueueType::Graphics)
|
||||
{
|
||||
m_cmd = std::make_unique<GnmCommandBufferDraw>(m_device);
|
||||
m_cmd = std::make_unique<GnmCommandBufferDraw>(m_device, objects);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_cmd = std::make_unique<GnmCommandBufferDispatch>(m_device);
|
||||
m_cmd = std::make_unique<GnmCommandBufferDispatch>(m_device, objects);
|
||||
}
|
||||
|
||||
#ifdef GPCS4_NO_GRAPHICS
|
||||
m_cmd = std::make_unique<GnmCommandBufferDummy>(m_device);
|
||||
m_cmd = std::make_unique<GnmCommandBufferDummy>(m_device, objects);
|
||||
#endif
|
||||
|
||||
m_cp->attachCommandBuffer(m_cmd.get());
|
||||
|
|
|
@ -155,14 +155,14 @@ namespace sce
|
|||
viewport.minDepth = 0.0f;
|
||||
viewport.maxDepth = 1.0f;
|
||||
|
||||
ctx->setViewports(1, &viewport);
|
||||
ctx->setScissors(1, &dstRect);
|
||||
ctx->setViewports(1, &viewport, &dstRect);
|
||||
|
||||
VltRenderTargets renderTargets;
|
||||
renderTargets.color[0].view = dstView;
|
||||
renderTargets.color[0].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
|
||||
ctx->bindRenderTargets(renderTargets);
|
||||
|
||||
VltAttachment targetAttachment = {
|
||||
dstView,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
|
||||
};
|
||||
ctx->bindRenderTarget(0, targetAttachment);
|
||||
ctx->clearRenderTarget(
|
||||
dstView, VK_IMAGE_ASPECT_COLOR_BIT, VkClearValue());
|
||||
ctx->transformImage(
|
||||
|
|
|
@ -142,6 +142,20 @@ namespace sce::vlt
|
|||
VkStencilOpState stencilOpBack;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Depth-stencil clear
|
||||
*
|
||||
* Defines the depth and stencil
|
||||
* clear values and state
|
||||
*/
|
||||
struct VltDepthStencilClear
|
||||
{
|
||||
VkBool32 enableDepthClear;
|
||||
VkClearValue depthValue;
|
||||
VkBool32 enableStencilClear;
|
||||
VkClearValue stencilValue;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Logic op state
|
||||
* Defines a logic op.
|
||||
|
|
|
@ -852,6 +852,22 @@ namespace sce::vlt
|
|||
m_flags.set(VltContextFlag::GpDirtyPipelineState);
|
||||
}
|
||||
|
||||
void VltContext::setDepthStencilClear(
|
||||
const VltDepthStencilClear& dsClear)
|
||||
{
|
||||
m_state.cb.attachmentOps.depth.loadOp = dsClear.enableDepthClear
|
||||
? VK_ATTACHMENT_LOAD_OP_CLEAR
|
||||
: VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
m_state.cb.attachmentOps.stencil.loadOp = dsClear.enableStencilClear
|
||||
? VK_ATTACHMENT_LOAD_OP_CLEAR
|
||||
: VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
|
||||
m_state.cb.clearValues.depth = dsClear.depthValue;
|
||||
m_state.cb.clearValues.stencil = dsClear.stencilValue;
|
||||
|
||||
m_flags.set(VltContextFlag::GpDirtyFramebufferState);
|
||||
}
|
||||
|
||||
void VltContext::setLogicOpState(
|
||||
const VltLogicOpState& lo)
|
||||
{
|
||||
|
@ -943,20 +959,20 @@ namespace sce::vlt
|
|||
// Perform the clear when starting the render pass
|
||||
if (clearAspects & VK_IMAGE_ASPECT_COLOR_BIT)
|
||||
{
|
||||
m_state.cb.attachmentOps.colorOps[attachmentIndex] = newOp;
|
||||
m_state.cb.clearValues.colorValue[attachmentIndex].color = clearValue.color;
|
||||
m_state.cb.attachmentOps.color[attachmentIndex] = newOp;
|
||||
m_state.cb.clearValues.color[attachmentIndex].color = clearValue.color;
|
||||
}
|
||||
|
||||
if (clearAspects & VK_IMAGE_ASPECT_DEPTH_BIT)
|
||||
{
|
||||
m_state.cb.attachmentOps.depthOps = newOp;
|
||||
m_state.cb.clearValues.depthValue.depthStencil.depth = clearValue.depthStencil.depth;
|
||||
m_state.cb.attachmentOps.depth = newOp;
|
||||
m_state.cb.clearValues.depth.depthStencil.depth = clearValue.depthStencil.depth;
|
||||
}
|
||||
|
||||
if (clearAspects & VK_IMAGE_ASPECT_STENCIL_BIT)
|
||||
{
|
||||
m_state.cb.attachmentOps.depthOps = newOp;
|
||||
m_state.cb.clearValues.depthValue.depthStencil.stencil = clearValue.depthStencil.stencil;
|
||||
m_state.cb.attachmentOps.depth = newOp;
|
||||
m_state.cb.clearValues.depth.depthStencil.stencil = clearValue.depthStencil.stencil;
|
||||
}
|
||||
|
||||
m_flags.set(VltContextFlag::GpDirtyFramebufferState);
|
||||
|
@ -1925,7 +1941,7 @@ namespace sce::vlt
|
|||
void VltContext::resetFramebufferOps()
|
||||
{
|
||||
VltFrameBufferOps ops;
|
||||
ops.depthOps = m_state.cb.renderTargets.depth.view != nullptr
|
||||
ops.depth = m_state.cb.renderTargets.depth.view != nullptr
|
||||
? VltAttachmentOps{
|
||||
VK_ATTACHMENT_LOAD_OP_LOAD,
|
||||
VK_ATTACHMENT_STORE_OP_STORE
|
||||
|
@ -1934,7 +1950,7 @@ namespace sce::vlt
|
|||
|
||||
for (uint32_t i = 0; i < MaxNumRenderTargets; i++)
|
||||
{
|
||||
ops.colorOps[i] = m_state.cb.renderTargets.color[i].view != nullptr
|
||||
ops.color[i] = m_state.cb.renderTargets.color[i].view != nullptr
|
||||
? VltAttachmentOps{
|
||||
VK_ATTACHMENT_LOAD_OP_LOAD,
|
||||
VK_ATTACHMENT_STORE_OP_STORE
|
||||
|
|
|
@ -202,6 +202,13 @@ namespace sce::vlt
|
|||
const VltDepthStencilState& ds);
|
||||
|
||||
/**
|
||||
* \brief Sets depth stencil clear
|
||||
* \param [in] ds New state object
|
||||
*/
|
||||
void setDepthStencilClear(
|
||||
const VltDepthStencilClear& dsClear);
|
||||
|
||||
/**
|
||||
* \brief Sets logic op state
|
||||
* \param [in] lo New state object
|
||||
*/
|
||||
|
|
|
@ -201,23 +201,23 @@ namespace sce::vlt
|
|||
|
||||
void VltFramebuffer::setAttachmentClearValues(const VltFrameBufferClearValues& values)
|
||||
{
|
||||
m_depthAttachment.clearValue.depthStencil = values.depthValue.depthStencil;
|
||||
m_depthAttachment.clearValue.depthStencil = values.depth.depthStencil;
|
||||
|
||||
for (uint32_t i = 0; i < MaxNumRenderTargets; i++)
|
||||
{
|
||||
m_colorAttachments[i].clearValue.color = values.colorValue[i].color;
|
||||
m_colorAttachments[i].clearValue.color = values.color[i].color;
|
||||
}
|
||||
}
|
||||
|
||||
void VltFramebuffer::setAttachmentOps(const VltFrameBufferOps& ops)
|
||||
{
|
||||
m_depthAttachment.loadOp = ops.depthOps.loadOp;
|
||||
m_depthAttachment.storeOp = ops.depthOps.storeOp;
|
||||
m_depthAttachment.loadOp = ops.depth.loadOp;
|
||||
m_depthAttachment.storeOp = ops.depth.storeOp;
|
||||
|
||||
for (uint32_t i = 0; i < MaxNumRenderTargets; i++)
|
||||
{
|
||||
m_colorAttachments[i].loadOp = ops.colorOps[i].loadOp;
|
||||
m_colorAttachments[i].storeOp = ops.colorOps[i].storeOp;
|
||||
m_colorAttachments[i].loadOp = ops.color[i].loadOp;
|
||||
m_colorAttachments[i].storeOp = ops.color[i].storeOp;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,20 +17,22 @@ namespace sce::vlt
|
|||
*/
|
||||
struct VltAttachmentOps
|
||||
{
|
||||
VkAttachmentLoadOp loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
VkAttachmentStoreOp storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
VkAttachmentLoadOp loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
VkAttachmentStoreOp storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
};
|
||||
|
||||
struct VltFrameBufferOps
|
||||
{
|
||||
VltAttachmentOps depthOps;
|
||||
VltAttachmentOps colorOps[MaxNumRenderTargets];
|
||||
VltAttachmentOps depth;
|
||||
VltAttachmentOps stencil;
|
||||
VltAttachmentOps color[MaxNumRenderTargets];
|
||||
};
|
||||
|
||||
struct VltFrameBufferClearValues
|
||||
{
|
||||
VkClearValue colorValue[MaxNumRenderTargets];
|
||||
VkClearValue depthValue;
|
||||
VkClearValue color[MaxNumRenderTargets];
|
||||
VkClearValue depth;
|
||||
VkClearValue stencil;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
|
||||
#include "Gnm/GnmConstant.h"
|
||||
#include "Sce/SceGnmDriver.h"
|
||||
#include "Sce/SceResourceTracker.h"
|
||||
#include "Sce/SceLabelManager.h"
|
||||
#include "Sce/SceVideoOut.h"
|
||||
|
||||
LOG_CHANNEL(Graphic.VirtualGPU);
|
||||
|
|
|
@ -49,16 +49,6 @@ namespace sce
|
|||
*/
|
||||
SceGnmDriver& gnmDriver();
|
||||
|
||||
/**
|
||||
* \brief Get GPU resource tracker.
|
||||
*/
|
||||
SceResourceTracker& resourceTracker();
|
||||
|
||||
/**
|
||||
* \brief Get GPU label manager.
|
||||
*/
|
||||
Gnm::GnmLabelManager& labelManager();
|
||||
|
||||
/**
|
||||
* \brief Global GPU mode.
|
||||
*
|
||||
|
|
Loading…
Reference in a new issue