forked from suyu/suyu
GPU: Added asserts to our code for handling the QUERY_GET GPU command.
This is based on research from nouveau. Many things are currently unknown and will require hwtests in the future. This commit also stubs QueryMode::Write2 to do the same as Write. Nouveau code treats them interchangeably, it is currently unknown what the difference is.
This commit is contained in:
parent
62937798a0
commit
f208953585
2 changed files with 53 additions and 2 deletions
|
@ -147,11 +147,36 @@ void Maxwell3D::ProcessQueryGet() {
|
||||||
// VAddr before writing.
|
// VAddr before writing.
|
||||||
VAddr address = memory_manager.PhysicalToVirtualAddress(sequence_address);
|
VAddr address = memory_manager.PhysicalToVirtualAddress(sequence_address);
|
||||||
|
|
||||||
|
// TODO(Subv): Support the other query units.
|
||||||
|
ASSERT_MSG(regs.query.query_get.unit == Regs::QueryUnit::Crop,
|
||||||
|
"Units other than CROP are unimplemented");
|
||||||
|
ASSERT_MSG(regs.query.query_get.short_query,
|
||||||
|
"Writing the entire query result structure is unimplemented");
|
||||||
|
|
||||||
|
u32 value = Memory::Read32(address);
|
||||||
|
u32 result = 0;
|
||||||
|
|
||||||
|
// TODO(Subv): Support the other query variables
|
||||||
|
switch (regs.query.query_get.select) {
|
||||||
|
case Regs::QuerySelect::Zero:
|
||||||
|
result = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
UNIMPLEMENTED_MSG("Unimplemented query select type %u",
|
||||||
|
static_cast<u32>(regs.query.query_get.select.Value()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(Subv): Research and implement how query sync conditions work.
|
||||||
|
|
||||||
switch (regs.query.query_get.mode) {
|
switch (regs.query.query_get.mode) {
|
||||||
case Regs::QueryMode::Write: {
|
case Regs::QueryMode::Write:
|
||||||
|
case Regs::QueryMode::Write2: {
|
||||||
// Write the current query sequence to the sequence address.
|
// Write the current query sequence to the sequence address.
|
||||||
u32 sequence = regs.query.query_sequence;
|
u32 sequence = regs.query.query_sequence;
|
||||||
Memory::Write32(address, sequence);
|
Memory::Write32(address, sequence);
|
||||||
|
|
||||||
|
// TODO(Subv): Write the proper query response structure to the address when not using short
|
||||||
|
// mode.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -46,6 +46,29 @@ public:
|
||||||
enum class QueryMode : u32 {
|
enum class QueryMode : u32 {
|
||||||
Write = 0,
|
Write = 0,
|
||||||
Sync = 1,
|
Sync = 1,
|
||||||
|
// TODO(Subv): It is currently unknown what the difference between method 2 and method 0
|
||||||
|
// is.
|
||||||
|
Write2 = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class QueryUnit : u32 {
|
||||||
|
VFetch = 1,
|
||||||
|
VP = 2,
|
||||||
|
Rast = 4,
|
||||||
|
StrmOut = 5,
|
||||||
|
GP = 6,
|
||||||
|
ZCull = 7,
|
||||||
|
Prop = 10,
|
||||||
|
Crop = 15,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class QuerySelect : u32 {
|
||||||
|
Zero = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class QuerySyncCondition : u32 {
|
||||||
|
NotEqual = 0,
|
||||||
|
GreaterThan = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class ShaderProgram : u32 {
|
enum class ShaderProgram : u32 {
|
||||||
|
@ -476,7 +499,10 @@ public:
|
||||||
u32 raw;
|
u32 raw;
|
||||||
BitField<0, 2, QueryMode> mode;
|
BitField<0, 2, QueryMode> mode;
|
||||||
BitField<4, 1, u32> fence;
|
BitField<4, 1, u32> fence;
|
||||||
BitField<12, 4, u32> unit;
|
BitField<12, 4, QueryUnit> unit;
|
||||||
|
BitField<16, 1, QuerySyncCondition> sync_cond;
|
||||||
|
BitField<23, 5, QuerySelect> select;
|
||||||
|
BitField<28, 1, u32> short_query;
|
||||||
} query_get;
|
} query_get;
|
||||||
|
|
||||||
GPUVAddr QueryAddress() const {
|
GPUVAddr QueryAddress() const {
|
||||||
|
|
Loading…
Reference in a new issue