mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-23 16:41: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 */
|
||||
private:
|
||||
struct Shader {
|
||||
|
@ -47,6 +47,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
||||
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_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_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)
|
||||
@ -62,6 +63,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
||||
return; \
|
||||
}
|
||||
#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_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)
|
||||
@ -433,6 +435,18 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
||||
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:
|
||||
break;
|
||||
}
|
||||
|
@ -281,6 +281,12 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
||||
Register<0x800, std::array<type::SetProgramInfo, type::StageCount>> setProgram;
|
||||
|
||||
Register<0x8C0, u32[0x20]> firmwareCall;
|
||||
|
||||
struct ConstantBufferSelector {
|
||||
u32 size;
|
||||
type::Address address;
|
||||
};
|
||||
Register<0x8E0, ConstantBufferSelector> constantBufferSelector;
|
||||
};
|
||||
static_assert(sizeof(Registers) == (RegisterCount * sizeof(u32)));
|
||||
#pragma pack(pop)
|
||||
|
Loading…
Reference in New Issue
Block a user