gl_state_tracker: Implement dirty flags for vertex formats
This commit is contained in:
parent
6530144ccb
commit
69ad6279e4
|
@ -120,7 +120,11 @@ void RasterizerOpenGL::CheckExtensions() {
|
||||||
|
|
||||||
void RasterizerOpenGL::SetupVertexFormat() {
|
void RasterizerOpenGL::SetupVertexFormat() {
|
||||||
auto& gpu = system.GPU().Maxwell3D();
|
auto& gpu = system.GPU().Maxwell3D();
|
||||||
const auto& regs = gpu.regs;
|
auto& flags = gpu.dirty.flags;
|
||||||
|
if (!flags[Dirty::VertexFormats]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
flags[Dirty::VertexFormats] = false;
|
||||||
|
|
||||||
MICROPROFILE_SCOPE(OpenGL_VAO);
|
MICROPROFILE_SCOPE(OpenGL_VAO);
|
||||||
|
|
||||||
|
@ -130,25 +134,31 @@ void RasterizerOpenGL::SetupVertexFormat() {
|
||||||
// avoid OpenGL errors.
|
// avoid OpenGL errors.
|
||||||
// TODO(Subv): Analyze the shader to identify which attributes are actually used and don't
|
// TODO(Subv): Analyze the shader to identify which attributes are actually used and don't
|
||||||
// assume every shader uses them all.
|
// assume every shader uses them all.
|
||||||
for (u32 index = 0; index < 16; ++index) {
|
for (std::size_t index = 0; index < 16; ++index) {
|
||||||
const auto& attrib = regs.vertex_attrib_format[index];
|
if (!flags[Dirty::VertexFormat0 + index]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
flags[Dirty::VertexFormat0 + index] = false;
|
||||||
|
|
||||||
|
const auto attrib = gpu.regs.vertex_attrib_format[index];
|
||||||
|
const auto gl_index = static_cast<GLuint>(index);
|
||||||
|
|
||||||
// Ignore invalid attributes.
|
// Ignore invalid attributes.
|
||||||
if (!attrib.IsValid()) {
|
if (!attrib.IsValid()) {
|
||||||
glDisableVertexAttribArray(index);
|
glDisableVertexAttribArray(gl_index);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
glEnableVertexAttribArray(index);
|
glEnableVertexAttribArray(gl_index);
|
||||||
|
|
||||||
if (attrib.type == Maxwell::VertexAttribute::Type::SignedInt ||
|
if (attrib.type == Maxwell::VertexAttribute::Type::SignedInt ||
|
||||||
attrib.type == Maxwell::VertexAttribute::Type::UnsignedInt) {
|
attrib.type == Maxwell::VertexAttribute::Type::UnsignedInt) {
|
||||||
glVertexAttribIFormat(index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib),
|
glVertexAttribIFormat(gl_index, attrib.ComponentCount(),
|
||||||
attrib.offset);
|
MaxwellToGL::VertexType(attrib), attrib.offset);
|
||||||
} else {
|
} else {
|
||||||
glVertexAttribFormat(index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib),
|
glVertexAttribFormat(gl_index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib),
|
||||||
attrib.IsNormalized() ? GL_TRUE : GL_FALSE, attrib.offset);
|
attrib.IsNormalized() ? GL_TRUE : GL_FALSE, attrib.offset);
|
||||||
}
|
}
|
||||||
glVertexAttribBinding(index, attrib.buffer);
|
glVertexAttribBinding(gl_index, attrib.buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,15 @@ void SetupDirtyColorMasks(Tables& tables) {
|
||||||
FillBlock(tables[1], OFF(color_mask), NUM(color_mask), ColorMasks);
|
FillBlock(tables[1], OFF(color_mask), NUM(color_mask), ColorMasks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetupDirtyVertexFormat(Tables& tables) {
|
||||||
|
for (std::size_t i = 0; i < Regs::NumVertexAttributes; ++i) {
|
||||||
|
const std::size_t offset = OFF(vertex_attrib_format) + i * NUM(vertex_attrib_format[0]);
|
||||||
|
FillBlock(tables[0], offset, NUM(vertex_attrib_format[0]), VertexFormat0 + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
FillBlock(tables[1], OFF(vertex_attrib_format), Regs::NumVertexAttributes, VertexFormats);
|
||||||
|
}
|
||||||
|
|
||||||
void SetupDirtyViewports(Tables& tables) {
|
void SetupDirtyViewports(Tables& tables) {
|
||||||
for (std::size_t i = 0; i < Regs::NumViewports; ++i) {
|
for (std::size_t i = 0; i < Regs::NumViewports; ++i) {
|
||||||
const std::size_t transf_offset = OFF(viewport_transform) + i * NUM(viewport_transform[0]);
|
const std::size_t transf_offset = OFF(viewport_transform) + i * NUM(viewport_transform[0]);
|
||||||
|
@ -117,6 +126,7 @@ void StateTracker::Initialize() {
|
||||||
SetupDirtyColorMasks(tables);
|
SetupDirtyColorMasks(tables);
|
||||||
SetupDirtyViewports(tables);
|
SetupDirtyViewports(tables);
|
||||||
SetupDirtyScissors(tables);
|
SetupDirtyScissors(tables);
|
||||||
|
SetupDirtyVertexFormat(tables);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace OpenGL
|
} // namespace OpenGL
|
||||||
|
|
|
@ -20,6 +20,8 @@ enum : u8 {
|
||||||
First = VideoCommon::Dirty::LastCommonEntry,
|
First = VideoCommon::Dirty::LastCommonEntry,
|
||||||
|
|
||||||
VertexFormats,
|
VertexFormats,
|
||||||
|
VertexFormat0,
|
||||||
|
VertexFormat31 = VertexFormat0 + 31,
|
||||||
|
|
||||||
VertexBuffers,
|
VertexBuffers,
|
||||||
VertexBuffer0,
|
VertexBuffer0,
|
||||||
|
@ -66,6 +68,16 @@ public:
|
||||||
|
|
||||||
void Initialize();
|
void Initialize();
|
||||||
|
|
||||||
|
void NotifyScreenDrawVertexArray() {
|
||||||
|
auto& flags = system.GPU().Maxwell3D().dirty.flags;
|
||||||
|
flags[OpenGL::Dirty::VertexFormats] = true;
|
||||||
|
flags[OpenGL::Dirty::VertexFormat0 + 0] = true;
|
||||||
|
flags[OpenGL::Dirty::VertexFormat0 + 1] = true;
|
||||||
|
|
||||||
|
flags[OpenGL::Dirty::VertexBuffers] = true;
|
||||||
|
flags[OpenGL::Dirty::VertexBuffer0] = true;
|
||||||
|
}
|
||||||
|
|
||||||
void NotifyViewport0() {
|
void NotifyViewport0() {
|
||||||
auto& flags = system.GPU().Maxwell3D().dirty.flags;
|
auto& flags = system.GPU().Maxwell3D().dirty.flags;
|
||||||
flags[OpenGL::Dirty::Viewports] = true;
|
flags[OpenGL::Dirty::Viewports] = true;
|
||||||
|
|
|
@ -576,6 +576,7 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
|
||||||
glNamedBufferSubData(vertex_buffer.handle, 0, sizeof(vertices), std::data(vertices));
|
glNamedBufferSubData(vertex_buffer.handle, 0, sizeof(vertices), std::data(vertices));
|
||||||
|
|
||||||
// TODO: Signal state tracker about these changes
|
// TODO: Signal state tracker about these changes
|
||||||
|
state_tracker.NotifyScreenDrawVertexArray();
|
||||||
state_tracker.NotifyViewport0();
|
state_tracker.NotifyViewport0();
|
||||||
state_tracker.NotifyScissor0();
|
state_tracker.NotifyScissor0();
|
||||||
state_tracker.NotifyColorMask0();
|
state_tracker.NotifyColorMask0();
|
||||||
|
@ -608,6 +609,8 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
|
||||||
static_cast<GLfloat>(layout.height));
|
static_cast<GLfloat>(layout.height));
|
||||||
glDepthRangeIndexed(0, 0.0, 0.0);
|
glDepthRangeIndexed(0, 0.0, 0.0);
|
||||||
|
|
||||||
|
glEnableVertexAttribArray(PositionLocation);
|
||||||
|
glEnableVertexAttribArray(TexCoordLocation);
|
||||||
glVertexAttribFormat(PositionLocation, 2, GL_FLOAT, GL_FALSE,
|
glVertexAttribFormat(PositionLocation, 2, GL_FLOAT, GL_FALSE,
|
||||||
offsetof(ScreenRectVertex, position));
|
offsetof(ScreenRectVertex, position));
|
||||||
glVertexAttribFormat(TexCoordLocation, 2, GL_FLOAT, GL_FALSE,
|
glVertexAttribFormat(TexCoordLocation, 2, GL_FLOAT, GL_FALSE,
|
||||||
|
|
Reference in New Issue