mirror of
https://github.com/Inori/GPCS4.git
synced 2024-06-02 19:38:19 -04:00
refactory some render state and shader
This commit is contained in:
parent
32277e2d83
commit
747ab5d998
|
@ -1,26 +1,17 @@
|
|||
#include "GcnHeader.h"
|
||||
#include "GcnConstants.h"
|
||||
#include "GcnDecoder.h"
|
||||
#include "GcnProgramInfo.h"
|
||||
#include "Gnm/GnmConstant.h"
|
||||
|
||||
|
||||
LOG_CHANNEL(Graphic.Gcn.GcnHeader);
|
||||
|
||||
using namespace sce::Gnm;
|
||||
|
||||
namespace sce::gcn
|
||||
{
|
||||
GcnHeader::GcnHeader(const uint8_t* shaderCode)
|
||||
{
|
||||
parseHeader(shaderCode);
|
||||
extractResourceTable(shaderCode);
|
||||
}
|
||||
|
||||
GcnHeader::~GcnHeader()
|
||||
{
|
||||
}
|
||||
|
||||
void GcnHeader::parseHeader(
|
||||
const uint8_t* shaderCode)
|
||||
GcnBinaryInfo::GcnBinaryInfo(const uint8_t* shaderCode)
|
||||
{
|
||||
const uint32_t* token = reinterpret_cast<const uint32_t*>(shaderCode);
|
||||
const uint32_t tokenMovVccHi = 0xBEEB03FF;
|
||||
|
@ -31,7 +22,64 @@ namespace sce::gcn
|
|||
// but if it is, we can still search for the header magic 'OrbShdr'
|
||||
LOG_ASSERT(token[0] == tokenMovVccHi, "first instruction is not s_mov_b32 vcc_hi, #imm");
|
||||
|
||||
const ShaderBinaryInfo* binaryInfo = reinterpret_cast<const ShaderBinaryInfo*>(token + (token[1] + 1) * 2);
|
||||
m_binInfo = reinterpret_cast<const ShaderBinaryInfo*>(token + (token[1] + 1) * 2);
|
||||
}
|
||||
|
||||
GcnBinaryInfo::~GcnBinaryInfo()
|
||||
{
|
||||
}
|
||||
|
||||
GcnHeader::GcnHeader(const uint8_t* shaderCode)
|
||||
{
|
||||
parseHeader(shaderCode);
|
||||
extractResourceTable(shaderCode);
|
||||
}
|
||||
|
||||
GcnHeader::~GcnHeader()
|
||||
{
|
||||
}
|
||||
|
||||
GcnProgramType GcnHeader::type() const
|
||||
{
|
||||
GcnProgramType result;
|
||||
ShaderBinaryType binType = static_cast<ShaderBinaryType>(m_binInfo.m_type);
|
||||
switch (binType)
|
||||
{
|
||||
case ShaderBinaryType::kPixelShader:
|
||||
result = GcnProgramType::PixelShader;
|
||||
break;
|
||||
case ShaderBinaryType::kVertexShader:
|
||||
result = GcnProgramType::VertexShader;
|
||||
break;
|
||||
case ShaderBinaryType::kComputeShader:
|
||||
result = GcnProgramType::ComputeShader;
|
||||
break;
|
||||
case ShaderBinaryType::kGeometryShader:
|
||||
result = GcnProgramType::GeometryShader;
|
||||
break;
|
||||
case ShaderBinaryType::kHullShader:
|
||||
result = GcnProgramType::HullShader;
|
||||
break;
|
||||
case ShaderBinaryType::kDomainShader:
|
||||
result = GcnProgramType::DomainShader;
|
||||
break;
|
||||
case ShaderBinaryType::kLocalShader:
|
||||
case ShaderBinaryType::kExportShader:
|
||||
case ShaderBinaryType::kUnknown:
|
||||
default:
|
||||
LOG_ASSERT(false, "unknown shader type.");
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void GcnHeader::parseHeader(
|
||||
const uint8_t* shaderCode)
|
||||
{
|
||||
|
||||
GcnBinaryInfo info(shaderCode);
|
||||
|
||||
const ShaderBinaryInfo* binaryInfo = info.info();
|
||||
std::memcpy(&m_binInfo, binaryInfo, sizeof(ShaderBinaryInfo));
|
||||
|
||||
// Get usage masks and input usage slots
|
||||
|
@ -154,4 +202,6 @@ namespace sce::gcn
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace sce::gcn
|
|
@ -9,6 +9,8 @@
|
|||
|
||||
namespace sce::gcn
|
||||
{
|
||||
enum class GcnProgramType;
|
||||
|
||||
/**
|
||||
* \brief Represent a resource bound to a GCN shader
|
||||
*/
|
||||
|
@ -35,6 +37,54 @@ namespace sce::gcn
|
|||
|
||||
using GcnShaderResourceTable = std::vector<GcnShaderResource>;
|
||||
|
||||
/**
|
||||
* \brief Light weight binary information parser
|
||||
*
|
||||
* Data in this class is not persistent, will become
|
||||
* invalid when shader code released.
|
||||
*/
|
||||
class GcnBinaryInfo
|
||||
{
|
||||
public:
|
||||
GcnBinaryInfo(
|
||||
const uint8_t* shaderCode);
|
||||
~GcnBinaryInfo();
|
||||
|
||||
/**
|
||||
* \brief Code length
|
||||
*
|
||||
* Gcn instruction code length in bytes.
|
||||
* Does not include header and
|
||||
* other meta information
|
||||
*/
|
||||
uint32_t length() const
|
||||
{
|
||||
return m_binInfo->m_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Unique key
|
||||
*
|
||||
* Used to identify the shader
|
||||
*/
|
||||
GcnShaderKey key() const
|
||||
{
|
||||
return GcnShaderKey(
|
||||
m_binInfo->m_shaderHash0, m_binInfo->m_crc32);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Information of shader binary
|
||||
*/
|
||||
const ShaderBinaryInfo* info() const
|
||||
{
|
||||
return m_binInfo;
|
||||
}
|
||||
|
||||
private:
|
||||
const ShaderBinaryInfo* m_binInfo = nullptr;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Header information
|
||||
|
@ -54,6 +104,8 @@ namespace sce::gcn
|
|||
const uint8_t* shaderCode);
|
||||
~GcnHeader();
|
||||
|
||||
GcnProgramType type() const;
|
||||
|
||||
/**
|
||||
* \brief Unique id of the shader
|
||||
*/
|
||||
|
@ -71,11 +123,6 @@ namespace sce::gcn
|
|||
return m_binInfo.m_length;
|
||||
}
|
||||
|
||||
const ShaderBinaryInfo& getShaderBinaryInfo() const
|
||||
{
|
||||
return m_binInfo;
|
||||
}
|
||||
|
||||
const InputUsageSlotTable& getInputUsageSlotTable() const
|
||||
{
|
||||
return m_inputUsageSlotTable;
|
||||
|
|
|
@ -16,11 +16,9 @@ LOG_CHANNEL(Graphic.Gcn.GcnModule);
|
|||
|
||||
namespace sce::gcn
|
||||
{
|
||||
GcnModule::GcnModule(
|
||||
GcnProgramType type,
|
||||
const uint8_t* code) :
|
||||
m_programInfo(type),
|
||||
GcnModule::GcnModule(const uint8_t* code) :
|
||||
m_header(code),
|
||||
m_programInfo(m_header.type()),
|
||||
m_code(code)
|
||||
{
|
||||
}
|
||||
|
@ -39,11 +37,6 @@ namespace sce::gcn
|
|||
GcnCodeSlice slice(start, end);
|
||||
|
||||
auto insList = this->decodeShader(slice);
|
||||
|
||||
//if (this->name() == "PSSHDR_58D2050651B6B50A")
|
||||
//{
|
||||
// __debugbreak();
|
||||
//}
|
||||
|
||||
// Generate global information
|
||||
GcnAnalysisInfo analysisInfo;
|
||||
|
|
|
@ -22,9 +22,7 @@ namespace sce::gcn
|
|||
class GcnModule
|
||||
{
|
||||
public:
|
||||
GcnModule(
|
||||
GcnProgramType type,
|
||||
const uint8_t* code);
|
||||
GcnModule(const uint8_t* code);
|
||||
~GcnModule();
|
||||
|
||||
/**
|
||||
|
@ -82,9 +80,9 @@ namespace sce::gcn
|
|||
void dumpShader() const;
|
||||
|
||||
private:
|
||||
GcnProgramInfo m_programInfo;
|
||||
GcnHeader m_header;
|
||||
const uint8_t* m_code;
|
||||
GcnHeader m_header;
|
||||
GcnProgramInfo m_programInfo;
|
||||
const uint8_t* m_code;
|
||||
|
||||
GcnShaderResourceTable m_resourceTable;
|
||||
};
|
||||
|
|
|
@ -6,6 +6,19 @@
|
|||
|
||||
namespace sce::gcn
|
||||
{
|
||||
enum class ShaderBinaryType : uint8_t
|
||||
{
|
||||
kPixelShader = 0, ///< PS stage shader.
|
||||
kVertexShader = 1, ///< VS stage shader
|
||||
kExportShader = 2,
|
||||
kLocalShader = 3,
|
||||
kComputeShader = 4, ///< CS stage shader.
|
||||
kGeometryShader = 5,
|
||||
kUnknown = 6,
|
||||
kHullShader = 7, ///< HS stage shader.
|
||||
kDomainShader = 8, ///< DS stage shader with embedded CS stage frontend shader.
|
||||
} ShaderType;
|
||||
|
||||
struct ShaderBinaryInfo
|
||||
{
|
||||
uint8_t m_signature[7]; // 'OrbShdr'
|
||||
|
|
|
@ -12,9 +12,9 @@ namespace sce::gcn
|
|||
{
|
||||
public:
|
||||
GcnShaderKey(
|
||||
uint32_t crc, uint32_t hash)
|
||||
uint32_t hash, uint32_t crc)
|
||||
{
|
||||
m_key = util::concat<uint64_t>(crc, hash);
|
||||
m_key = util::concat<uint64_t>(hash, crc);
|
||||
}
|
||||
|
||||
~GcnShaderKey() = default;
|
||||
|
@ -29,6 +29,11 @@ namespace sce::gcn
|
|||
return util::str::format("SHDR_%llX", m_key);
|
||||
}
|
||||
|
||||
bool operator==(const GcnShaderKey& other) const
|
||||
{
|
||||
return m_key == other.m_key;
|
||||
}
|
||||
|
||||
private:
|
||||
uint64_t m_key;
|
||||
};
|
||||
|
|
|
@ -77,4 +77,10 @@ namespace sce::Gnm
|
|||
{
|
||||
GnmShaderContext shaderContext = {};
|
||||
};
|
||||
|
||||
struct GnmRenderState
|
||||
{
|
||||
GnmGraphicsState gp;
|
||||
GnmComputeState cp;
|
||||
};
|
||||
} // namespace sce::Gnm
|
84
GPCS4/Graphics/Gnm/GnmShader.cpp
Normal file
84
GPCS4/Graphics/Gnm/GnmShader.cpp
Normal file
|
@ -0,0 +1,84 @@
|
|||
#include "GnmShader.h"
|
||||
#include "Violet/VltShader.h"
|
||||
#include "Gcn/GcnModule.h"
|
||||
#include "Gcn/GcnShaderMeta.h"
|
||||
|
||||
|
||||
LOG_CHANNEL(Graphic.Gnm.GnmShader);
|
||||
|
||||
using namespace sce::gcn;
|
||||
using namespace sce::vlt;
|
||||
|
||||
namespace sce::Gnm
|
||||
{
|
||||
GnmShader::GnmShader() :
|
||||
m_shader(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
GnmShader::GnmShader(const vlt::VltShaderKey* key,
|
||||
const gcn::GcnModuleInfo* moduleInfo,
|
||||
const GcnShaderMeta& meta,
|
||||
const void* code)
|
||||
{
|
||||
const std::string name = key->toString();
|
||||
LOG_DEBUG("Compiling shader %s", name.c_str());
|
||||
|
||||
GcnModule module(
|
||||
reinterpret_cast<const uint8_t*>(code));
|
||||
|
||||
m_shader = module.compile(meta, *moduleInfo);
|
||||
m_shader->setShaderKey(*key);
|
||||
}
|
||||
|
||||
GnmShader::~GnmShader()
|
||||
{
|
||||
}
|
||||
|
||||
GcnShaderModuleSet::GcnShaderModuleSet()
|
||||
{
|
||||
}
|
||||
|
||||
GcnShaderModuleSet::~GcnShaderModuleSet()
|
||||
{
|
||||
}
|
||||
|
||||
GnmShader GcnShaderModuleSet::GetShaderModule(const VltShaderKey* key,
|
||||
const GcnModuleInfo* moduleInfo,
|
||||
const GcnShaderMeta& meta,
|
||||
const void* code)
|
||||
{
|
||||
// Use the shader's unique key for the lookup
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
|
||||
auto entry = m_modules.find(*key);
|
||||
if (entry != m_modules.end())
|
||||
{
|
||||
return entry->second;
|
||||
}
|
||||
}
|
||||
|
||||
// This shader has not been compiled yet, so we have to create a
|
||||
// new module. This takes a while, so we won't lock the structure.
|
||||
GnmShader shader = GnmShader(key, moduleInfo, meta, code);
|
||||
|
||||
// Insert the new module into the lookup table. If another thread
|
||||
// has compiled the same shader in the meantime, we should return
|
||||
// that object instead and discard the newly created module.
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
|
||||
auto status = m_modules.insert({ *key, shader });
|
||||
if (!status.second)
|
||||
{
|
||||
return status.first->second;
|
||||
}
|
||||
}
|
||||
|
||||
return std::move(shader);
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace sce::Gnm
|
79
GPCS4/Graphics/Gnm/GnmShader.h
Normal file
79
GPCS4/Graphics/Gnm/GnmShader.h
Normal file
|
@ -0,0 +1,79 @@
|
|||
#pragma once
|
||||
|
||||
#include "GnmCommon.h"
|
||||
#include "Gcn/GcnModInfo.h"
|
||||
#include "Violet/VltHash.h"
|
||||
|
||||
#include <mutex>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace sce::vlt
|
||||
{
|
||||
class VltShaderKey;
|
||||
} // namespace sce::vlt
|
||||
|
||||
namespace sce::gcn
|
||||
{
|
||||
union GcnShaderMeta;
|
||||
} // namespace sce::vlt
|
||||
|
||||
namespace sce::Gnm
|
||||
{
|
||||
/**
|
||||
* \brief Common shader object
|
||||
*
|
||||
* Stores the compiled SPIR-V shader and the
|
||||
* hash of the original gcn shader, which can be
|
||||
* used to identify the shader.
|
||||
*/
|
||||
class GnmShader
|
||||
{
|
||||
public:
|
||||
GnmShader();
|
||||
GnmShader(const vlt::VltShaderKey* key,
|
||||
const gcn::GcnModuleInfo* moduleInfo,
|
||||
const GcnShaderMeta& meta,
|
||||
const void* code);
|
||||
~GnmShader();
|
||||
|
||||
vlt::Rc<VltShader> getShader() const
|
||||
{
|
||||
return m_shader;
|
||||
}
|
||||
|
||||
private:
|
||||
vlt::Rc<vlt::VltShader> m_shader;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Shader module set
|
||||
*
|
||||
* Some applications may compile the same shader multiple
|
||||
* times, so we should cache the resulting shader modules
|
||||
* and reuse them rather than creating new ones. This
|
||||
* class is thread-safe.
|
||||
*/
|
||||
class GcnShaderModuleSet
|
||||
{
|
||||
|
||||
public:
|
||||
GcnShaderModuleSet();
|
||||
~GcnShaderModuleSet();
|
||||
|
||||
GnmShader GetShaderModule(
|
||||
const vlt::VltShaderKey* key,
|
||||
const gcn::GcnModuleInfo* moduleInfo,
|
||||
const GcnShaderMeta& meta,
|
||||
const void* code);
|
||||
|
||||
private:
|
||||
std::mutex m_mutex;
|
||||
|
||||
std::unordered_map<
|
||||
vlt::VltShaderKey,
|
||||
GnmShader,
|
||||
vlt::VltHash,
|
||||
vlt::VltEq> m_modules;
|
||||
};
|
||||
|
||||
} // namespace sce::Gnm
|
|
@ -58,24 +58,27 @@ namespace sce::vlt
|
|||
};
|
||||
|
||||
/**
|
||||
* \brief Depth bounds range
|
||||
*
|
||||
* Stores depth bounds values.
|
||||
*/
|
||||
struct VltDepthBoundsRange
|
||||
* \brief Depth bounds
|
||||
*
|
||||
* Stores depth bounds values.
|
||||
*/
|
||||
struct VltDepthBounds
|
||||
{
|
||||
float minDepthBounds;
|
||||
float maxDepthBounds;
|
||||
VkBool32 enableDepthBounds;
|
||||
float minDepthBounds;
|
||||
float maxDepthBounds;
|
||||
|
||||
bool operator==(const VltDepthBoundsRange& other) const
|
||||
{
|
||||
return minDepthBounds == other.minDepthBounds &&
|
||||
bool operator==(const VltDepthBounds& other) const
|
||||
{
|
||||
return enableDepthBounds == other.enableDepthBounds &&
|
||||
minDepthBounds == other.minDepthBounds &&
|
||||
maxDepthBounds == other.maxDepthBounds;
|
||||
}
|
||||
|
||||
bool operator!=(const VltDepthBoundsRange& other) const
|
||||
bool operator!=(const VltDepthBounds& other) const
|
||||
{
|
||||
return minDepthBounds != other.minDepthBounds ||
|
||||
return enableDepthBounds != other.enableDepthBounds ||
|
||||
minDepthBounds != other.minDepthBounds ||
|
||||
maxDepthBounds != other.maxDepthBounds;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -84,24 +84,27 @@ namespace sce::vlt
|
|||
m_device->createCommandList(queueType));
|
||||
}
|
||||
|
||||
void VltContext::bindRenderTarget(
|
||||
uint32_t slot,
|
||||
const VltAttachment& target)
|
||||
void VltContext::bindRenderTargets(const VltRenderTargets& targets)
|
||||
{
|
||||
m_state.cb.renderTargets.color[slot] = target;
|
||||
// Set up default render pass ops
|
||||
m_state.cb.renderTargets = targets;
|
||||
|
||||
resetFramebufferOps();
|
||||
this->resetFramebufferOps();
|
||||
|
||||
m_flags.set(VltContextFlag::GpDirtyFramebuffer);
|
||||
if (m_state.cb.framebuffer == nullptr || !m_state.cb.framebuffer->matchTargets(targets))
|
||||
{
|
||||
// Create a new framebuffer object next
|
||||
// time we start rendering something
|
||||
m_flags.set(VltContextFlag::GpDirtyFramebuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Don't redundantly spill the render pass if
|
||||
// the same render targets are bound again
|
||||
m_flags.clr(VltContextFlag::GpDirtyFramebuffer);
|
||||
}
|
||||
}
|
||||
|
||||
void VltContext::bindDepthRenderTarget(
|
||||
const VltAttachment& depthTarget)
|
||||
{
|
||||
m_state.cb.renderTargets.depth = depthTarget;
|
||||
|
||||
m_flags.set(VltContextFlag::GpDirtyFramebuffer);
|
||||
}
|
||||
|
||||
void VltContext::bindIndexBuffer(
|
||||
const VltBufferSlice& buffer,
|
||||
|
@ -484,8 +487,8 @@ namespace sce::vlt
|
|||
m_state.gp.state.ds.enableDepthBoundsTest());
|
||||
|
||||
m_cmd->cmdSetDepthBounds(
|
||||
m_state.dyn.depthBoundsRange.minDepthBounds,
|
||||
m_state.dyn.depthBoundsRange.maxDepthBounds);
|
||||
m_state.dyn.depthBounds.minDepthBounds,
|
||||
m_state.dyn.depthBounds.maxDepthBounds);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -603,7 +606,8 @@ namespace sce::vlt
|
|||
|
||||
void VltContext::setViewports(
|
||||
uint32_t viewportCount,
|
||||
const VkViewport* viewports)
|
||||
const VkViewport* viewports,
|
||||
const VkRect2D* scissorRects)
|
||||
{
|
||||
if (m_state.gp.state.rs.viewportCount() != viewportCount)
|
||||
{
|
||||
|
@ -613,13 +617,13 @@ namespace sce::vlt
|
|||
|
||||
for (uint32_t i = 0; i < viewportCount; i++)
|
||||
{
|
||||
m_state.vp.viewports[i] = viewports[i];
|
||||
m_state.vp.viewports[i] = viewports[i];
|
||||
m_state.vp.scissorRects[i] = scissorRects[i];
|
||||
|
||||
// Vulkan viewports are not allowed to have a width
|
||||
// of zero (but zero height is allowed),
|
||||
// so we fall back to a dummy viewport
|
||||
// Vulkan viewports are not allowed to have a width or
|
||||
// height of zero, so we fall back to a dummy viewport
|
||||
// and instead set an empty scissor rect, which is legal.
|
||||
if (viewports[i].width == 0.0f)
|
||||
if (viewports[i].width == 0.0f || viewports[i].height == 0.0f)
|
||||
{
|
||||
m_state.vp.viewports[i] = VkViewport{
|
||||
0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f
|
||||
|
@ -634,27 +638,6 @@ namespace sce::vlt
|
|||
m_flags.set(VltContextFlag::GpDirtyViewport);
|
||||
}
|
||||
|
||||
void VltContext::setScissors(
|
||||
uint32_t scissorCount,
|
||||
const VkRect2D* scissorRects)
|
||||
{
|
||||
// Assume count of scissor and viewport are always equal.
|
||||
// In fact, these's only one scissor for Gnm
|
||||
if (m_state.gp.state.rs.viewportCount() != scissorCount)
|
||||
{
|
||||
m_state.gp.state.rs.setViewportCount(scissorCount);
|
||||
m_flags.set(VltContextFlag::GpDirtyPipelineState);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < scissorCount; i++)
|
||||
{
|
||||
m_state.vp.scissorRects[i] = scissorRects[i];
|
||||
}
|
||||
|
||||
m_flags.set(VltContextFlag::GpDirtyScissor);
|
||||
}
|
||||
|
||||
|
||||
void VltContext::setBlendConstants(
|
||||
VltBlendConstants blendConstants)
|
||||
{
|
||||
|
@ -675,25 +658,19 @@ namespace sce::vlt
|
|||
}
|
||||
}
|
||||
|
||||
void VltContext::setDepthBoundsTestEnable(
|
||||
VkBool32 depthBoundsTestEnable)
|
||||
void VltContext::setDepthBounds(VltDepthBounds depthBounds)
|
||||
{
|
||||
if (m_state.gp.state.ds.enableDepthBoundsTest() != depthBoundsTestEnable)
|
||||
if (m_state.dyn.depthBounds != depthBounds)
|
||||
{
|
||||
m_state.gp.state.ds.setEnableDepthBoundsTest(depthBoundsTestEnable);
|
||||
m_flags.set(VltContextFlag::GpDirtyPipelineState);
|
||||
}
|
||||
}
|
||||
|
||||
void VltContext::setDepthBoundsRange(
|
||||
VltDepthBoundsRange depthBoundsRange)
|
||||
{
|
||||
if (m_state.dyn.depthBoundsRange != depthBoundsRange)
|
||||
{
|
||||
m_state.dyn.depthBoundsRange = depthBoundsRange;
|
||||
m_state.dyn.depthBounds = depthBounds;
|
||||
m_flags.set(VltContextFlag::GpDirtyDepthBounds);
|
||||
}
|
||||
|
||||
if (m_state.gp.state.ds.enableDepthBoundsTest() != depthBounds.enableDepthBounds)
|
||||
{
|
||||
m_state.gp.state.ds.setEnableDepthBoundsTest(depthBounds.enableDepthBounds);
|
||||
m_flags.set(VltContextFlag::GpDirtyPipelineState);
|
||||
}
|
||||
}
|
||||
|
||||
void VltContext::setStencilReference(uint32_t reference)
|
||||
|
@ -901,15 +878,6 @@ namespace sce::vlt
|
|||
m_flags.set(VltContextFlag::GpDirtyPipelineState);
|
||||
}
|
||||
|
||||
void VltContext::setBlendMask(
|
||||
uint32_t attachment,
|
||||
VkColorComponentFlags writeMask)
|
||||
{
|
||||
m_state.gp.state.cbBlend[attachment].setColorWriteMask(writeMask);
|
||||
|
||||
m_flags.set(VltContextFlag::GpDirtyPipelineState);
|
||||
}
|
||||
|
||||
void VltContext::clearRenderTarget(
|
||||
const Rc<VltImageView>& imageView,
|
||||
VkImageAspectFlags clearAspects,
|
||||
|
@ -2037,4 +2005,5 @@ namespace sce::vlt
|
|||
}
|
||||
|
||||
|
||||
|
||||
} // namespace sce::vlt
|
|
@ -76,22 +76,15 @@ namespace sce::vlt
|
|||
void flushCommandList();
|
||||
|
||||
/**
|
||||
* \brief Sets render targets
|
||||
*
|
||||
* \param [in] slot Slot number
|
||||
* \param [in] targets Render targets to bind
|
||||
*/
|
||||
void bindRenderTarget(
|
||||
uint32_t slot,
|
||||
const VltAttachment& target);
|
||||
* \brief Sets render targets
|
||||
*
|
||||
* Creates a framebuffer on the fly if necessary
|
||||
* and binds it using \c bindFramebuffer.
|
||||
* \param [in] targets Render targets to bind
|
||||
*/
|
||||
void bindRenderTargets(
|
||||
const VltRenderTargets& targets);
|
||||
|
||||
/**
|
||||
* \brief Sets depth render targets
|
||||
*
|
||||
* \param [in] targets Render targets to bind
|
||||
*/
|
||||
void bindDepthRenderTarget(
|
||||
const VltAttachment& depthTarget);
|
||||
|
||||
/**
|
||||
* \brief Binds index buffer
|
||||
|
@ -226,36 +219,17 @@ namespace sce::vlt
|
|||
const VltBlendMode& blendMode);
|
||||
|
||||
/**
|
||||
* \brief Sets write mask for an attachment
|
||||
* \brief Sets viewports
|
||||
*
|
||||
* \param [in] attachment The attachment index
|
||||
* \param [in] writeMask The writeMask
|
||||
* \param [in] viewportCount Number of viewports
|
||||
* \param [in] viewports The viewports
|
||||
* \param [in] scissorRects Schissor rectangles
|
||||
*/
|
||||
void setBlendMask(
|
||||
uint32_t attachment,
|
||||
VkColorComponentFlags writeMask);
|
||||
|
||||
|
||||
/**
|
||||
* \brief Sets viewports
|
||||
*
|
||||
* \param [in] viewportCount Number of viewports
|
||||
* \param [in] viewports The viewports
|
||||
* \param [in] scissorRects Schissor rectangles
|
||||
*/
|
||||
void setViewports(
|
||||
uint32_t viewportCount,
|
||||
const VkViewport* viewports);
|
||||
const VkViewport* viewports,
|
||||
const VkRect2D* scissorRects);
|
||||
|
||||
/**
|
||||
* \brief Sets viewports
|
||||
*
|
||||
* \param [in] scissorCount Number of schissor rectangles
|
||||
* \param [in] scissorRects Schissor rectangles
|
||||
*/
|
||||
void setScissors(
|
||||
uint32_t scissorCount,
|
||||
const VkRect2D* scissorRects);
|
||||
|
||||
/**
|
||||
* \brief Sets blend constants
|
||||
|
@ -278,22 +252,15 @@ namespace sce::vlt
|
|||
void setDepthBias(
|
||||
VltDepthBias depthBias);
|
||||
|
||||
/**
|
||||
* \brief Sets depth bounds enable state
|
||||
*
|
||||
* Enables or disables the depth bounds test.
|
||||
*/
|
||||
void setDepthBoundsTestEnable(
|
||||
VkBool32 depthBoundsTestEnable);
|
||||
|
||||
/**
|
||||
* \brief Sets depth bounds
|
||||
*
|
||||
* Updates the depth bounds values.
|
||||
* \param [in] depthBoundsRange Depth bounds range
|
||||
* Enables or disables the depth bounds test,
|
||||
* and updates the values if necessary.
|
||||
* \param [in] depthBounds Depth bounds
|
||||
*/
|
||||
void setDepthBoundsRange(
|
||||
VltDepthBoundsRange depthBoundsRange);
|
||||
void setDepthBounds(
|
||||
VltDepthBounds depthBounds);
|
||||
|
||||
/**
|
||||
* \brief Sets stencil reference
|
||||
|
|
|
@ -37,7 +37,6 @@ namespace sce::vlt
|
|||
GpDirtyDepthBounds, ///< Depth bounds have changed
|
||||
GpDirtyStencilRef, ///< Stencil reference has changed
|
||||
GpDirtyViewport, ///< Viewport has changed
|
||||
GpDirtyScissor, ///< Scissor has changed
|
||||
GpDirtyPredicate, ///< Predicate has changed
|
||||
GpDynamicBlendConstants, ///< Blend constants are dynamic
|
||||
GpDynamicDepthBias, ///< Depth bias is dynamic
|
||||
|
@ -125,10 +124,10 @@ namespace sce::vlt
|
|||
|
||||
struct VltDynamicState
|
||||
{
|
||||
VltBlendConstants blendConstants = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
VltDepthBias depthBias = { 0.0f, 0.0f, 0.0f };
|
||||
VltDepthBoundsRange depthBoundsRange = { 0.0f, 1.0f };
|
||||
uint32_t stencilReference = 0;
|
||||
VltBlendConstants blendConstants = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
VltDepthBias depthBias = { 0.0f, 0.0f, 0.0f };
|
||||
VltDepthBounds depthBounds = { false, 0.0f, 1.0f };
|
||||
uint32_t stencilReference = 0;
|
||||
};
|
||||
|
||||
struct VltCondRenderState
|
||||
|
|
|
@ -149,7 +149,6 @@ namespace sce::vlt
|
|||
dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE;
|
||||
}
|
||||
|
||||
|
||||
if (state.useDynamicBlendConstants())
|
||||
dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_BLEND_CONSTANTS;
|
||||
|
||||
|
|
|
@ -107,8 +107,6 @@ namespace sce::vlt
|
|||
m_flags.set(VltShaderFlag::ExportsViewportIndexLayerFromVertexStage);
|
||||
}
|
||||
}
|
||||
|
||||
updateShaderKey(code);
|
||||
}
|
||||
|
||||
VltShader::~VltShader()
|
||||
|
@ -168,7 +166,10 @@ namespace sce::vlt
|
|||
// Do not fix binding id if we read from a external binary file.
|
||||
m_idOffsets.clear();
|
||||
|
||||
updateShaderKey(m_code.decompress());
|
||||
auto code = m_code.decompress();
|
||||
alg::Sha1Hash hash = alg::Sha1Hash::compute(code.data(), code.size());
|
||||
m_key = VltShaderKey(m_stage, hash);
|
||||
m_hash = m_key.hash();
|
||||
}
|
||||
|
||||
void VltShader::eliminateInput(SpirvCodeBuffer& code, uint32_t location)
|
||||
|
@ -380,14 +381,6 @@ namespace sce::vlt
|
|||
}
|
||||
}
|
||||
|
||||
void VltShader::updateShaderKey(const gcn::SpirvCodeBuffer& code)
|
||||
{
|
||||
alg::Sha1Hash hash = alg::Sha1Hash::compute(code.data(), code.size());
|
||||
m_key = VltShaderKey(m_stage, hash);
|
||||
m_hash = m_key.hash();
|
||||
}
|
||||
|
||||
|
||||
VltShaderModule::VltShaderModule() :
|
||||
m_device(nullptr), m_stage()
|
||||
{
|
||||
|
|
|
@ -251,6 +251,16 @@ namespace sce::vlt
|
|||
return m_key;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Sets the shader key
|
||||
* \param [in] key Unique key
|
||||
*/
|
||||
void setShaderKey(const VltShaderKey& key)
|
||||
{
|
||||
m_key = key;
|
||||
m_hash = key.hash();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get lookup hash
|
||||
*
|
||||
|
@ -287,7 +297,6 @@ namespace sce::vlt
|
|||
}
|
||||
|
||||
private:
|
||||
void updateShaderKey(const gcn::SpirvCodeBuffer& code);
|
||||
|
||||
static void eliminateInput(gcn::SpirvCodeBuffer& code, uint32_t location);
|
||||
|
||||
|
@ -306,8 +315,6 @@ namespace sce::vlt
|
|||
|
||||
size_t m_o1IdxOffset = 0;
|
||||
size_t m_o1LocOffset = 0;
|
||||
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -4,7 +4,7 @@ namespace sce::vlt
|
|||
{
|
||||
VltShaderKey::VltShaderKey() :
|
||||
m_type(0),
|
||||
m_sha1(alg::Sha1Hash::compute(nullptr, 0))
|
||||
m_key(0, 0)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@ namespace sce::vlt
|
|||
prefix = "";
|
||||
}
|
||||
|
||||
return util::str::formatex(prefix, m_sha1.toString());
|
||||
return util::str::formatex(prefix, m_key.name());
|
||||
}
|
||||
|
||||
size_t VltShaderKey::hash() const
|
||||
|
@ -44,14 +44,15 @@ namespace sce::vlt
|
|||
VltHashState result;
|
||||
result.add(uint32_t(m_type));
|
||||
|
||||
for (uint32_t i = 0; i < 5; i++)
|
||||
result.add(m_sha1.dword(i));
|
||||
uint64_t key = m_key.key();
|
||||
result.add(key);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool VltShaderKey::eq(const VltShaderKey& key) const
|
||||
bool VltShaderKey::eq(const VltShaderKey& other) const
|
||||
{
|
||||
return m_type == key.m_type && m_sha1 == key.m_sha1;
|
||||
return m_type == other.m_type &&
|
||||
m_key == other.m_key;
|
||||
}
|
||||
} // namespace sce::vlt
|
|
@ -1,8 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include "Sha1Hash.h"
|
||||
#include "VltCommon.h"
|
||||
#include "VltHash.h"
|
||||
#include "Gcn/GcnShaderKey.h"
|
||||
|
||||
namespace sce::vlt
|
||||
{
|
||||
|
@ -32,9 +32,9 @@ namespace sce::vlt
|
|||
*/
|
||||
VltShaderKey(
|
||||
VkShaderStageFlagBits stage,
|
||||
alg::Sha1Hash hash) :
|
||||
gcn::GcnShaderKey key) :
|
||||
m_type(stage),
|
||||
m_sha1(hash)
|
||||
m_key(key)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -53,14 +53,14 @@ namespace sce::vlt
|
|||
/**
|
||||
* \brief Checks whether two keys are equal
|
||||
*
|
||||
* \param [in] key The shader key to compare to
|
||||
* \param [in] other The shader key to compare to
|
||||
* \returns \c true if the two keys are equal
|
||||
*/
|
||||
bool eq(const VltShaderKey& key) const;
|
||||
bool eq(const VltShaderKey& other) const;
|
||||
|
||||
private:
|
||||
VkShaderStageFlags m_type;
|
||||
alg::Sha1Hash m_sha1;
|
||||
gcn::GcnShaderKey m_key;
|
||||
};
|
||||
|
||||
} // namespace sce::vlt
|
Loading…
Reference in a new issue