mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-24 02:21:51 +01:00
Implement Maxwell3D Constant Buffer Selector
The Constant Buffer Selector is used to point to a constant buffer that will be bound to a shader stage or updated with inline data.
This commit is contained in:
parent
afa34e320a
commit
9af9f1d41a
@ -511,6 +511,47 @@ namespace skyline::gpu::interconnect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Constant Buffers */
|
||||||
|
private:
|
||||||
|
struct ConstantBuffer {
|
||||||
|
IOVA iova;
|
||||||
|
u32 size;
|
||||||
|
GuestBuffer guest;
|
||||||
|
std::shared_ptr<BufferView> view;
|
||||||
|
};
|
||||||
|
ConstantBuffer constantBufferSelector; //!< The constant buffer selector is used to bind a constant buffer to a stage or update data in it
|
||||||
|
|
||||||
|
public:
|
||||||
|
void SetConstantBufferSelectorSize(u32 size) {
|
||||||
|
constantBufferSelector.size = size;
|
||||||
|
constantBufferSelector.view.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetConstantBufferSelectorIovaHigh(u32 high) {
|
||||||
|
constantBufferSelector.iova.high = high;
|
||||||
|
constantBufferSelector.view.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetConstantBufferSelectorIovaLow(u32 low) {
|
||||||
|
constantBufferSelector.iova.low = low;
|
||||||
|
constantBufferSelector.view.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
BufferView *GetConstantBufferSelectorView() {
|
||||||
|
if (constantBufferSelector.size == 0)
|
||||||
|
return nullptr;
|
||||||
|
else if (constantBufferSelector.view)
|
||||||
|
return &*constantBufferSelector.view;
|
||||||
|
|
||||||
|
if (constantBufferSelector.guest.mappings.empty()) {
|
||||||
|
auto mappings{channelCtx.asCtx->gmmu.TranslateRange(constantBufferSelector.iova, constantBufferSelector.size)};
|
||||||
|
constantBufferSelector.guest.mappings.assign(mappings.begin(), mappings.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
constantBufferSelector.view = gpu.buffer.FindOrCreate(constantBufferSelector.guest);
|
||||||
|
return constantBufferSelector.view.get();
|
||||||
|
}
|
||||||
|
|
||||||
/* Shader Program */
|
/* Shader Program */
|
||||||
private:
|
private:
|
||||||
struct Shader {
|
struct Shader {
|
||||||
|
@ -47,6 +47,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
void Maxwell3D::HandleMethod(u32 method, u32 argument) {
|
void Maxwell3D::HandleMethod(u32 method, u32 argument) {
|
||||||
#define MAXWELL3D_OFFSET(field) (sizeof(typeof(Registers::field)) - sizeof(std::remove_reference_t<decltype(*Registers::field)>)) / sizeof(u32)
|
#define MAXWELL3D_OFFSET(field) (sizeof(typeof(Registers::field)) - sizeof(std::remove_reference_t<decltype(*Registers::field)>)) / sizeof(u32)
|
||||||
#define MAXWELL3D_STRUCT_OFFSET(field, member) MAXWELL3D_OFFSET(field) + U32_OFFSET(std::remove_reference_t<decltype(*Registers::field)>, member)
|
#define MAXWELL3D_STRUCT_OFFSET(field, member) MAXWELL3D_OFFSET(field) + U32_OFFSET(std::remove_reference_t<decltype(*Registers::field)>, member)
|
||||||
|
#define MAXWELL3D_STRUCT_STRUCT_OFFSET(field, member, submember) MAXWELL3D_STRUCT_OFFSET(field, member) + U32_OFFSET(std::remove_reference_t<decltype(Registers::field->member)>, submember)
|
||||||
#define MAXWELL3D_ARRAY_OFFSET(field, index) MAXWELL3D_OFFSET(field) + ((sizeof(std::remove_reference_t<decltype(Registers::field[0])>) / sizeof(u32)) * index)
|
#define MAXWELL3D_ARRAY_OFFSET(field, index) MAXWELL3D_OFFSET(field) + ((sizeof(std::remove_reference_t<decltype(Registers::field[0])>) / sizeof(u32)) * index)
|
||||||
#define MAXWELL3D_ARRAY_STRUCT_OFFSET(field, index, member) MAXWELL3D_ARRAY_OFFSET(field, index) + U32_OFFSET(std::remove_reference_t<decltype(Registers::field[0])>, member)
|
#define MAXWELL3D_ARRAY_STRUCT_OFFSET(field, index, member) MAXWELL3D_ARRAY_OFFSET(field, index) + U32_OFFSET(std::remove_reference_t<decltype(Registers::field[0])>, member)
|
||||||
#define MAXWELL3D_ARRAY_STRUCT_STRUCT_OFFSET(field, index, member, submember) MAXWELL3D_ARRAY_STRUCT_OFFSET(field, index, member) + U32_OFFSET(decltype(Registers::field[0].member), submember)
|
#define MAXWELL3D_ARRAY_STRUCT_STRUCT_OFFSET(field, index, member, submember) MAXWELL3D_ARRAY_STRUCT_OFFSET(field, index, member) + U32_OFFSET(decltype(Registers::field[0].member), submember)
|
||||||
@ -62,6 +63,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
return; \
|
return; \
|
||||||
}
|
}
|
||||||
#define MAXWELL3D_STRUCT_CASE(field, member, content) MAXWELL3D_CASE_BASE(member, field->member, MAXWELL3D_STRUCT_OFFSET(field, member), content)
|
#define MAXWELL3D_STRUCT_CASE(field, member, content) MAXWELL3D_CASE_BASE(member, field->member, MAXWELL3D_STRUCT_OFFSET(field, member), content)
|
||||||
|
#define MAXWELL3D_STRUCT_STRUCT_CASE(field, member, submember, content) MAXWELL3D_CASE_BASE(submember, field->member.submember, MAXWELL3D_STRUCT_STRUCT_OFFSET(field, member, submember), content)
|
||||||
#define MAXWELL3D_ARRAY_CASE(field, index, content) MAXWELL3D_CASE_BASE(field, field[index], MAXWELL3D_ARRAY_OFFSET(field, index), content)
|
#define MAXWELL3D_ARRAY_CASE(field, index, content) MAXWELL3D_CASE_BASE(field, field[index], MAXWELL3D_ARRAY_OFFSET(field, index), content)
|
||||||
#define MAXWELL3D_ARRAY_STRUCT_CASE(field, index, member, content) MAXWELL3D_CASE_BASE(member, field[index].member, MAXWELL3D_ARRAY_STRUCT_OFFSET(field, index, member), content)
|
#define MAXWELL3D_ARRAY_STRUCT_CASE(field, index, member, content) MAXWELL3D_CASE_BASE(member, field[index].member, MAXWELL3D_ARRAY_STRUCT_OFFSET(field, index, member), content)
|
||||||
#define MAXWELL3D_ARRAY_STRUCT_STRUCT_CASE(field, index, member, submember, content) MAXWELL3D_CASE_BASE(submember, field[index].member.submember, MAXWELL3D_ARRAY_STRUCT_STRUCT_OFFSET(field, index, member, submember), content)
|
#define MAXWELL3D_ARRAY_STRUCT_STRUCT_CASE(field, index, member, submember, content) MAXWELL3D_CASE_BASE(submember, field[index].member.submember, MAXWELL3D_ARRAY_STRUCT_STRUCT_OFFSET(field, index, member, submember), content)
|
||||||
@ -433,6 +435,18 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
context.SetPrimitiveTopology(vertexBeginGl.topology);
|
context.SetPrimitiveTopology(vertexBeginGl.topology);
|
||||||
})
|
})
|
||||||
|
|
||||||
|
MAXWELL3D_STRUCT_CASE(constantBufferSelector, size, {
|
||||||
|
context.SetConstantBufferSelectorSize(size);
|
||||||
|
})
|
||||||
|
|
||||||
|
MAXWELL3D_STRUCT_STRUCT_CASE(constantBufferSelector, address, high, {
|
||||||
|
context.SetConstantBufferSelectorIovaHigh(high);
|
||||||
|
})
|
||||||
|
|
||||||
|
MAXWELL3D_STRUCT_STRUCT_CASE(constantBufferSelector, address, low, {
|
||||||
|
context.SetConstantBufferSelectorIovaLow(low);
|
||||||
|
})
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -281,6 +281,12 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
Register<0x800, std::array<type::SetProgramInfo, type::StageCount>> setProgram;
|
Register<0x800, std::array<type::SetProgramInfo, type::StageCount>> setProgram;
|
||||||
|
|
||||||
Register<0x8C0, u32[0x20]> firmwareCall;
|
Register<0x8C0, u32[0x20]> firmwareCall;
|
||||||
|
|
||||||
|
struct ConstantBufferSelector {
|
||||||
|
u32 size;
|
||||||
|
type::Address address;
|
||||||
|
};
|
||||||
|
Register<0x8E0, ConstantBufferSelector> constantBufferSelector;
|
||||||
};
|
};
|
||||||
static_assert(sizeof(Registers) == (RegisterCount * sizeof(u32)));
|
static_assert(sizeof(Registers) == (RegisterCount * sizeof(u32)));
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
Loading…
Reference in New Issue
Block a user