mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-31 14:52:11 +01:00
[d3d9] Reduce data copied for SWVP vertex decls
This commit is contained in:
parent
7de88ff993
commit
bbe851f6a2
@ -2953,14 +2953,19 @@ namespace dxvk {
|
||||
auto slice = dst->GetBufferSlice<D3D9_COMMON_BUFFER_TYPE_REAL>();
|
||||
slice = slice.subSlice(offset, slice.length() - offset);
|
||||
|
||||
D3D9CompactVertexElements elements;
|
||||
for (const D3DVERTEXELEMENT9& element : decl->GetElements()) {
|
||||
elements.emplace_back(element);
|
||||
}
|
||||
|
||||
EmitCs([this,
|
||||
cVertexElements = decl->GetElements(),
|
||||
cVertexElements = std::move(elements),
|
||||
cVertexCount = VertexCount,
|
||||
cStartIndex = SrcStartIndex,
|
||||
cInstanceCount = GetInstanceCount(),
|
||||
cBufferSlice = slice
|
||||
](DxvkContext* ctx) mutable {
|
||||
Rc<DxvkShader> shader = m_swvpEmulator.GetShaderModule(this, cVertexElements);
|
||||
Rc<DxvkShader> shader = m_swvpEmulator.GetShaderModule(this, std::move(cVertexElements));
|
||||
|
||||
auto drawInfo = GenerateDrawInfo(D3DPT_POINTLIST, cVertexCount, cInstanceCount);
|
||||
|
||||
|
@ -9,13 +9,14 @@ namespace dxvk {
|
||||
|
||||
// Doesn't compare everything, only what we use in SWVP.
|
||||
|
||||
size_t D3D9VertexDeclHash::operator () (const D3D9VertexElements& key) const {
|
||||
size_t D3D9VertexDeclHash::operator () (const D3D9CompactVertexElements& key) const {
|
||||
DxvkHashState hash;
|
||||
|
||||
std::hash<BYTE> bytehash;
|
||||
std::hash<WORD> wordhash;
|
||||
|
||||
for (auto& element : key) {
|
||||
for (uint32_t i = 0; i < key.size(); i++) {
|
||||
const auto& element = key[i];
|
||||
hash.add(wordhash(element.Stream));
|
||||
hash.add(wordhash(element.Offset));
|
||||
hash.add(bytehash(element.Type));
|
||||
@ -27,7 +28,7 @@ namespace dxvk {
|
||||
return hash;
|
||||
}
|
||||
|
||||
bool D3D9VertexDeclEq::operator () (const D3D9VertexElements& a, const D3D9VertexElements& b) const {
|
||||
bool D3D9VertexDeclEq::operator () (const D3D9CompactVertexElements& a, const D3D9CompactVertexElements& b) const {
|
||||
if (a.size() != b.size())
|
||||
return false;
|
||||
|
||||
@ -109,7 +110,7 @@ namespace dxvk {
|
||||
m_module.opLabel(m_module.allocateId());
|
||||
}
|
||||
|
||||
void compile(const D3D9VertexElements& elements) {
|
||||
void compile(const D3D9CompactVertexElements& elements) {
|
||||
uint32_t uint_t = m_module.defIntType(32, false);
|
||||
uint32_t float_t = m_module.defFloatType(32);
|
||||
uint32_t vec4_t = m_module.defVectorType(float_t, 4);
|
||||
@ -144,8 +145,9 @@ namespace dxvk {
|
||||
uint32_t primitiveId = m_module.opLoad(uint_t, primitiveIdPtr);
|
||||
|
||||
// The size of any given vertex
|
||||
uint32_t size = 0;
|
||||
for (const auto& element : elements) {
|
||||
uint32_t size = 0;
|
||||
for (uint32_t i = 0; i < elements.size(); i++) {
|
||||
const auto& element = elements[i];
|
||||
if (element.Stream == 0 && element.Type != D3DDECLTYPE_UNUSED) {
|
||||
size = std::max(size, element.Offset + GetDecltypeSize(D3DDECLTYPE(element.Type)));
|
||||
}
|
||||
@ -157,7 +159,8 @@ namespace dxvk {
|
||||
uint32_t thisVertexOffset = m_module.opIMul(uint_t, vertexSize, primitiveId);
|
||||
|
||||
|
||||
for (auto& element : elements) {
|
||||
for (uint32_t i = 0; i < elements.size(); i++) {
|
||||
const auto& element = elements[i];
|
||||
// Load the slot associated with this element
|
||||
DxsoSemantic semantic = { DxsoUsage(element.Usage), element.UsageIndex };
|
||||
|
||||
@ -304,7 +307,7 @@ namespace dxvk {
|
||||
|
||||
};
|
||||
|
||||
Rc<DxvkShader> D3D9SWVPEmulator::GetShaderModule(D3D9DeviceEx* pDevice, const D3D9VertexElements& elements) {
|
||||
Rc<DxvkShader> D3D9SWVPEmulator::GetShaderModule(D3D9DeviceEx* pDevice, D3D9CompactVertexElements&& elements) {
|
||||
// Use the shader's unique key for the lookup
|
||||
{ std::unique_lock<dxvk::mutex> lock(m_mutex);
|
||||
|
||||
@ -343,7 +346,8 @@ namespace dxvk {
|
||||
// that object instead and discard the newly created module.
|
||||
{ std::unique_lock<dxvk::mutex> lock(m_mutex);
|
||||
|
||||
auto status = m_modules.insert({ elements, shader });
|
||||
std::pair<D3D9CompactVertexElements, Rc<DxvkShader>> pair = { std::move(elements), shader };
|
||||
auto status = m_modules.insert(std::move(pair));
|
||||
if (!status.second)
|
||||
return status.first->second;
|
||||
}
|
||||
|
@ -11,26 +11,41 @@ namespace dxvk {
|
||||
class D3D9VertexDecl;
|
||||
class D3D9DeviceEx;
|
||||
|
||||
struct D3D9CompactVertexElement {
|
||||
uint16_t Stream : 4;
|
||||
uint16_t Type : 5;
|
||||
uint16_t Method : 3;
|
||||
uint16_t Usage : 4;
|
||||
uint16_t UsageIndex;
|
||||
uint16_t Offset;
|
||||
|
||||
D3D9CompactVertexElement(const D3DVERTEXELEMENT9& element)
|
||||
: Stream(element.Stream), Type(element.Type), Method(element.Method),
|
||||
Usage(element.Usage), UsageIndex(element.UsageIndex), Offset(element.Offset) {}
|
||||
};
|
||||
|
||||
using D3D9CompactVertexElements = small_vector<D3D9CompactVertexElement, 4>;
|
||||
|
||||
struct D3D9VertexDeclHash {
|
||||
size_t operator () (const D3D9VertexElements& key) const;
|
||||
size_t operator () (const D3D9CompactVertexElements& key) const;
|
||||
};
|
||||
|
||||
struct D3D9VertexDeclEq {
|
||||
bool operator () (const D3D9VertexElements& a, const D3D9VertexElements& b) const;
|
||||
bool operator () (const D3D9CompactVertexElements& a, const D3D9CompactVertexElements& b) const;
|
||||
};
|
||||
|
||||
class D3D9SWVPEmulator {
|
||||
|
||||
public:
|
||||
|
||||
Rc<DxvkShader> GetShaderModule(D3D9DeviceEx* pDevice, const D3D9VertexElements& elements);
|
||||
Rc<DxvkShader> GetShaderModule(D3D9DeviceEx* pDevice, D3D9CompactVertexElements&& elements);
|
||||
|
||||
private:
|
||||
|
||||
dxvk::mutex m_mutex;
|
||||
|
||||
std::unordered_map<
|
||||
D3D9VertexElements, Rc<DxvkShader>,
|
||||
D3D9CompactVertexElements, Rc<DxvkShader>,
|
||||
D3D9VertexDeclHash, D3D9VertexDeclEq> m_modules;
|
||||
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user