mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-12 04:54:17 +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>();
|
auto slice = dst->GetBufferSlice<D3D9_COMMON_BUFFER_TYPE_REAL>();
|
||||||
slice = slice.subSlice(offset, slice.length() - offset);
|
slice = slice.subSlice(offset, slice.length() - offset);
|
||||||
|
|
||||||
|
D3D9CompactVertexElements elements;
|
||||||
|
for (const D3DVERTEXELEMENT9& element : decl->GetElements()) {
|
||||||
|
elements.emplace_back(element);
|
||||||
|
}
|
||||||
|
|
||||||
EmitCs([this,
|
EmitCs([this,
|
||||||
cVertexElements = decl->GetElements(),
|
cVertexElements = std::move(elements),
|
||||||
cVertexCount = VertexCount,
|
cVertexCount = VertexCount,
|
||||||
cStartIndex = SrcStartIndex,
|
cStartIndex = SrcStartIndex,
|
||||||
cInstanceCount = GetInstanceCount(),
|
cInstanceCount = GetInstanceCount(),
|
||||||
cBufferSlice = slice
|
cBufferSlice = slice
|
||||||
](DxvkContext* ctx) mutable {
|
](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);
|
auto drawInfo = GenerateDrawInfo(D3DPT_POINTLIST, cVertexCount, cInstanceCount);
|
||||||
|
|
||||||
|
@ -9,13 +9,14 @@ namespace dxvk {
|
|||||||
|
|
||||||
// Doesn't compare everything, only what we use in SWVP.
|
// 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;
|
DxvkHashState hash;
|
||||||
|
|
||||||
std::hash<BYTE> bytehash;
|
std::hash<BYTE> bytehash;
|
||||||
std::hash<WORD> wordhash;
|
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.Stream));
|
||||||
hash.add(wordhash(element.Offset));
|
hash.add(wordhash(element.Offset));
|
||||||
hash.add(bytehash(element.Type));
|
hash.add(bytehash(element.Type));
|
||||||
@ -27,7 +28,7 @@ namespace dxvk {
|
|||||||
return hash;
|
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())
|
if (a.size() != b.size())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -109,7 +110,7 @@ namespace dxvk {
|
|||||||
m_module.opLabel(m_module.allocateId());
|
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 uint_t = m_module.defIntType(32, false);
|
||||||
uint32_t float_t = m_module.defFloatType(32);
|
uint32_t float_t = m_module.defFloatType(32);
|
||||||
uint32_t vec4_t = m_module.defVectorType(float_t, 4);
|
uint32_t vec4_t = m_module.defVectorType(float_t, 4);
|
||||||
@ -145,7 +146,8 @@ namespace dxvk {
|
|||||||
|
|
||||||
// The size of any given vertex
|
// The size of any given vertex
|
||||||
uint32_t size = 0;
|
uint32_t size = 0;
|
||||||
for (const auto& element : elements) {
|
for (uint32_t i = 0; i < elements.size(); i++) {
|
||||||
|
const auto& element = elements[i];
|
||||||
if (element.Stream == 0 && element.Type != D3DDECLTYPE_UNUSED) {
|
if (element.Stream == 0 && element.Type != D3DDECLTYPE_UNUSED) {
|
||||||
size = std::max(size, element.Offset + GetDecltypeSize(D3DDECLTYPE(element.Type)));
|
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);
|
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
|
// Load the slot associated with this element
|
||||||
DxsoSemantic semantic = { DxsoUsage(element.Usage), element.UsageIndex };
|
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
|
// Use the shader's unique key for the lookup
|
||||||
{ std::unique_lock<dxvk::mutex> lock(m_mutex);
|
{ std::unique_lock<dxvk::mutex> lock(m_mutex);
|
||||||
|
|
||||||
@ -343,7 +346,8 @@ namespace dxvk {
|
|||||||
// that object instead and discard the newly created module.
|
// that object instead and discard the newly created module.
|
||||||
{ std::unique_lock<dxvk::mutex> lock(m_mutex);
|
{ 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)
|
if (!status.second)
|
||||||
return status.first->second;
|
return status.first->second;
|
||||||
}
|
}
|
||||||
|
@ -11,26 +11,41 @@ namespace dxvk {
|
|||||||
class D3D9VertexDecl;
|
class D3D9VertexDecl;
|
||||||
class D3D9DeviceEx;
|
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 {
|
struct D3D9VertexDeclHash {
|
||||||
size_t operator () (const D3D9VertexElements& key) const;
|
size_t operator () (const D3D9CompactVertexElements& key) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct D3D9VertexDeclEq {
|
struct D3D9VertexDeclEq {
|
||||||
bool operator () (const D3D9VertexElements& a, const D3D9VertexElements& b) const;
|
bool operator () (const D3D9CompactVertexElements& a, const D3D9CompactVertexElements& b) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class D3D9SWVPEmulator {
|
class D3D9SWVPEmulator {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Rc<DxvkShader> GetShaderModule(D3D9DeviceEx* pDevice, const D3D9VertexElements& elements);
|
Rc<DxvkShader> GetShaderModule(D3D9DeviceEx* pDevice, D3D9CompactVertexElements&& elements);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
dxvk::mutex m_mutex;
|
dxvk::mutex m_mutex;
|
||||||
|
|
||||||
std::unordered_map<
|
std::unordered_map<
|
||||||
D3D9VertexElements, Rc<DxvkShader>,
|
D3D9CompactVertexElements, Rc<DxvkShader>,
|
||||||
D3D9VertexDeclHash, D3D9VertexDeclEq> m_modules;
|
D3D9VertexDeclHash, D3D9VertexDeclEq> m_modules;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user