[PICA] Depth buffering v1

This commit is contained in:
wheremyfoodat 2023-03-03 00:59:55 +02:00
parent d79fd1e198
commit eaab13b264
3 changed files with 67 additions and 7 deletions

View file

@ -72,12 +72,19 @@ public:
void setColourFormat(u32 format) { colourBufferFormat = static_cast<ColourBuffer::Formats>(format); }
void setDepthFormat(DepthBuffer::Formats format) { depthBufferFormat = format; }
void setDepthFormat(u32 format) { depthBufferFormat = static_cast<DepthBuffer::Formats>(format); }
void setDepthFormat(u32 format) {
if (format == 2) {
Helpers::panic("[PICA] Undocumented depth-stencil mode!");
}
depthBufferFormat = static_cast<DepthBuffer::Formats>(format);
}
void setColourBufferLoc(u32 loc) { colourBufferLoc = loc; }
void setDepthBufferLoc(u32 loc) { depthBufferLoc = loc; }
void setupBlending();
void bindDepthBuffer();
static constexpr u32 vertexBufferSize = 0x1500;
};

View file

@ -40,13 +40,13 @@ struct ColourBuffer {
void allocate() {
// Create texture for the FBO, setting up filters and the like
// Reading back the current texture is slow, but allocate calls should be and far between.
// Reading back the current texture is slow, but allocate calls should be few and far between.
// If this becomes a bottleneck, we can fix it semi-easily
auto prevTexture = OpenGL::getTex2D();
texture.create(size.x(), size.y(), GL_RGBA8);
texture.bind();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
texture.setMinFilter(OpenGL::Linear);
texture.setMagFilter(OpenGL::Linear);
glBindTexture(GL_TEXTURE_2D, prevTexture);
//Helpers::panic("Creating FBO: %d, %d\n", size.x(), size.y());
@ -115,14 +115,47 @@ struct DepthBuffer {
DepthBuffer() : valid(false) {}
DepthBuffer(u32 loc, Formats format, u32 x, u32 y, bool valid = true) :
location(loc), format(format), size({x, y}), valid(valid) {}
location(loc), format(format), size({x, y}), valid(valid) {
u64 endLoc = (u64)loc + sizeInBytes();
// Check if start and end are valid here
range = Interval<u32>(loc, (u32)endLoc);
}
bool hasStencil() {
return format == Formats::Depth24Stencil8;
}
void allocate() {
printf("Make this depth buffer allocate itself\n");
// Create texture for the FBO, setting up filters and the like
// Reading back the current texture is slow, but allocate calls should be few and far between.
// If this becomes a bottleneck, we can fix it semi-easily
auto prevTexture = OpenGL::getTex2D();
// Internal formats for the texture based on format
static constexpr std::array<GLenum, 4> internalFormats = {
GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT24, GL_DEPTH24_STENCIL8
};
// Format of the texture
static constexpr std::array<GLenum, 4> formats = {
GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_DEPTH_STENCIL
};
static constexpr std::array<GLenum, 4> types = {
GL_FLOAT, GL_FLOAT, GL_FLOAT, GL_UNSIGNED_INT_24_8
};
auto internalFormat = internalFormats[(int)format];
auto fmt = formats[(int)format];
auto type = types[(int)format];
texture.createDSTexture(size.x(), size.y(), internalFormat, fmt, nullptr, type);
texture.bind();
texture.setMinFilter(OpenGL::Linear);
texture.setMagFilter(OpenGL::Linear);
glBindTexture(GL_TEXTURE_2D, prevTexture);
}
void free() {

View file

@ -291,14 +291,18 @@ void Renderer::drawVertices(OpenGL::Primitives primType, Vertex* vertices, u32 c
float viewportHeight = f24::fromRaw(regs[PICAInternalRegs::ViewportHeight] & 0xffffff).toFloat32() * 2.0;
OpenGL::setViewport(viewportWidth, viewportHeight);
// Note: The code below must execute after we've bound the colour buffer & its framebuffer
// Because it attaches a depth texture to the aforementioned colour buffer
if (depthEnable) {
OpenGL::enableDepth();
glDepthFunc(depthModes[depthFunc]);
glDepthMask(depthWriteEnable ? GL_TRUE : GL_FALSE);
bindDepthBuffer();
} else {
if (depthWriteEnable) {
OpenGL::enableDepth();
glDepthFunc(GL_ALWAYS);
bindDepthBuffer();
} else {
OpenGL::disableDepth();
}
@ -364,8 +368,24 @@ OpenGL::Framebuffer Renderer::getColourFBO() {
}
}
void Renderer::bindDepthBuffer() {
// Similar logic as the getColourFBO function
DepthBuffer sampleBuffer(depthBufferLoc, depthBufferFormat, fbSize.x(), fbSize.y());
auto buffer = depthBufferCache.find(sampleBuffer);
GLuint tex;
if (buffer.has_value()) {
tex = buffer.value().get().texture.m_handle;
} else {
tex = depthBufferCache.add(sampleBuffer).texture.m_handle;
}
auto attachment = depthBufferFormat == DepthBuffer::Formats::Depth24Stencil8 ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT;
glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, tex, 0);
}
OpenGL::Texture Renderer::getTexture(Texture& tex) {
// Similar logic as the getColourFBO/getDepthBuffer functions
// Similar logic as the getColourFBO/bindDepthBuffer functions
auto buffer = textureCache.find(tex);
if (buffer.has_value()) {