mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-31 14:52:11 +01:00
[dxbc] Add support for multiple streams in geometry shaders
This commit is contained in:
parent
a42f03e32d
commit
6a5fe2247a
@ -796,7 +796,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
|
|
||||||
void DxbcCompiler::emitDclStream(const DxbcShaderInstruction& ins) {
|
void DxbcCompiler::emitDclStream(const DxbcShaderInstruction& ins) {
|
||||||
if (ins.dst[0].idx[0].offset != 0)
|
if (ins.dst[0].idx[0].offset != 0 && m_moduleInfo.xfb == nullptr)
|
||||||
Logger::err("Dxbc: Multiple streams not supported");
|
Logger::err("Dxbc: Multiple streams not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2053,6 +2053,16 @@ namespace dxvk {
|
|||||||
|
|
||||||
|
|
||||||
void DxbcCompiler::emitGeometryEmit(const DxbcShaderInstruction& ins) {
|
void DxbcCompiler::emitGeometryEmit(const DxbcShaderInstruction& ins) {
|
||||||
|
// In xfb mode we might have multiple streams, so
|
||||||
|
// we have to figure out which stream to write to
|
||||||
|
uint32_t streamId = 0;
|
||||||
|
uint32_t streamVar = 0;
|
||||||
|
|
||||||
|
if (m_moduleInfo.xfb != nullptr) {
|
||||||
|
streamId = ins.dstCount > 0 ? ins.dst[0].idx[0].offset : 0;
|
||||||
|
streamVar = m_module.constu32(streamId);
|
||||||
|
}
|
||||||
|
|
||||||
// Checking the negation is easier for EmitThenCut/EmitThenCutStream
|
// Checking the negation is easier for EmitThenCut/EmitThenCutStream
|
||||||
bool doEmit = ins.op != DxbcOpcode::Cut && ins.op != DxbcOpcode::CutStream;
|
bool doEmit = ins.op != DxbcOpcode::Cut && ins.op != DxbcOpcode::CutStream;
|
||||||
bool doCut = ins.op != DxbcOpcode::Emit && ins.op != DxbcOpcode::EmitStream;
|
bool doCut = ins.op != DxbcOpcode::Emit && ins.op != DxbcOpcode::EmitStream;
|
||||||
@ -2061,11 +2071,11 @@ namespace dxvk {
|
|||||||
emitOutputSetup();
|
emitOutputSetup();
|
||||||
emitClipCullStore(DxbcSystemValue::ClipDistance, m_clipDistances);
|
emitClipCullStore(DxbcSystemValue::ClipDistance, m_clipDistances);
|
||||||
emitClipCullStore(DxbcSystemValue::CullDistance, m_cullDistances);
|
emitClipCullStore(DxbcSystemValue::CullDistance, m_cullDistances);
|
||||||
m_module.opEmitVertex();
|
m_module.opEmitVertex(streamVar);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (doCut)
|
if (doCut)
|
||||||
m_module.opEndPrimitive();
|
m_module.opEndPrimitive(streamVar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -6009,6 +6019,14 @@ namespace dxvk {
|
|||||||
m_module.enableCapability(spv::CapabilityClipDistance);
|
m_module.enableCapability(spv::CapabilityClipDistance);
|
||||||
m_module.enableCapability(spv::CapabilityCullDistance);
|
m_module.enableCapability(spv::CapabilityCullDistance);
|
||||||
|
|
||||||
|
// Enable capabilities for xfb mode if necessary
|
||||||
|
if (m_moduleInfo.xfb != nullptr) {
|
||||||
|
m_module.enableCapability(spv::CapabilityGeometryStreams);
|
||||||
|
m_module.enableCapability(spv::CapabilityTransformFeedback);
|
||||||
|
|
||||||
|
m_module.setExecutionMode(m_entryPointId, spv::ExecutionModeXfb);
|
||||||
|
}
|
||||||
|
|
||||||
// Declare the per-vertex output block. Outputs are not
|
// Declare the per-vertex output block. Outputs are not
|
||||||
// declared as arrays, instead they will be flushed when
|
// declared as arrays, instead they will be flushed when
|
||||||
// calling EmitVertex.
|
// calling EmitVertex.
|
||||||
|
@ -2937,13 +2937,25 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SpirvModule::opEmitVertex() {
|
void SpirvModule::opEmitVertex(
|
||||||
|
uint32_t streamId) {
|
||||||
|
if (streamId == 0) {
|
||||||
m_code.putIns (spv::OpEmitVertex, 1);
|
m_code.putIns (spv::OpEmitVertex, 1);
|
||||||
|
} else {
|
||||||
|
m_code.putIns (spv::OpEmitStreamVertex, 2);
|
||||||
|
m_code.putWord(streamId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SpirvModule::opEndPrimitive() {
|
void SpirvModule::opEndPrimitive(
|
||||||
|
uint32_t streamId) {
|
||||||
|
if (streamId == 0) {
|
||||||
m_code.putIns (spv::OpEndPrimitive, 1);
|
m_code.putIns (spv::OpEndPrimitive, 1);
|
||||||
|
} else {
|
||||||
|
m_code.putIns (spv::OpEndStreamPrimitive, 2);
|
||||||
|
m_code.putWord(streamId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1022,9 +1022,11 @@ namespace dxvk {
|
|||||||
|
|
||||||
void opKill();
|
void opKill();
|
||||||
|
|
||||||
void opEmitVertex();
|
void opEmitVertex(
|
||||||
|
uint32_t streamId);
|
||||||
|
|
||||||
void opEndPrimitive();
|
void opEndPrimitive(
|
||||||
|
uint32_t streamId);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user