Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions include/dolphin/gx/GXAurora.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#ifndef DOLPHIN_GXAURORA_H
#define DOLPHIN_GXAURORA_H

#include <dolphin/types.h>

#if __cplusplus
extern "C" {
#endif
Expand Down Expand Up @@ -58,6 +60,19 @@ void GXPopDebugGroup();
*/
void GXInsertDebugMarker(const char* label);

/**
* Create an offscreen framebuffer and switch rendering to it.
* All subsequent GX rendering will target this framebuffer until GXRestoreFrameBuffer() is called.
* Use GXCopyTex to resolve the offscreen content into a texture.
*/
void GXCreateFrameBuffer(u32 width, u32 height);

/**
* Restore rendering to the main EFB framebuffer.
* Must be called after GXCreateFrameBuffer() to resume normal rendering.
*/
void GXRestoreFrameBuffer(void);

#if __cplusplus
}
#endif
Expand Down
13 changes: 13 additions & 0 deletions lib/dolphin/gx/GXAurora.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
#include "__gx.h"
#include "gx.hpp"

#include "../../gfx/common.hpp"
#include "../../gx/fifo.hpp"

static void GXWriteString(const char* label) {
auto length = strlen(label);

Expand All @@ -30,3 +33,13 @@ void GXInsertDebugMarker(const char* label) {
GX_WRITE_AURORA(GX_LOAD_AURORA_DEBUG_MARKER_INSERT);
GXWriteString(label);
}

void GXCreateFrameBuffer(u32 width, u32 height) {
aurora::gx::fifo::drain();
aurora::gfx::begin_offscreen(width, height);
}

void GXRestoreFrameBuffer() {
aurora::gx::fifo::drain();
aurora::gfx::end_offscreen();
}
56 changes: 23 additions & 33 deletions lib/dolphin/gx/GXFrameBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,9 @@ void GXSetTexCopySrc(u16 left, u16 top, u16 wd, u16 ht) { g_gxState.texCopySrc =
void GXSetDispCopyDst(u16 wd, u16 ht) {}

void GXSetTexCopyDst(u16 wd, u16 ht, GXTexFmt fmt, GXBool mipmap) {
// TODO texture copy scaling (mipmap)
g_gxState.texCopyFmt = fmt;
g_gxState.texCopyDstWidth = wd;
g_gxState.texCopyDstHeight = ht;
}

// TODO GXSetDispCopyFrame2Field
Expand Down Expand Up @@ -125,25 +126,29 @@ void GXCopyDisp(void* dest, GXBool clear) {}

void GXCopyTex(void* dest, GXBool clear) {
const auto& rect = g_gxState.texCopySrc;
const wgpu::Extent3D size{
.width = static_cast<uint32_t>(rect.width),
.height = static_cast<uint32_t>(rect.height),
.depthOrArrayLayers = 1,
};
const u32 dstWidth = g_gxState.texCopyDstWidth;
const u32 dstHeight = g_gxState.texCopyDstHeight;
const auto texCopyFmt = g_gxState.texCopyFmt;

const aurora::gx::GXState::CopyTextureKey key{
.dest = dest,
.width = size.width,
.height = size.height,
.format = g_gxState.texCopyFmt,
.width = dstWidth,
.height = dstHeight,
.format = texCopyFmt,
};
auto it = g_gxState.copyTextureCache.find(key);
if (it == g_gxState.copyTextureCache.end()) {
// Configure the texture swizzle to use alpha 1.0 if targeting RGB565 or EFB doesn't have alpha
const auto fmt = g_gxState.texCopyFmt == GX_TF_RGB565 || g_gxState.pixelFmt == GX_PF_RGB8_Z24 ||
g_gxState.pixelFmt == GX_PF_RGB565_Z16
? GX_TF_RGB565
: GX_TF_RGBA8;
auto handle = aurora::gfx::new_render_texture(rect.width, rect.height, fmt, "Resolved Texture");
aurora::gfx::TextureHandle handle;
if (aurora::gfx::tex_copy_conv::needs_conversion(texCopyFmt)) {
handle = aurora::gfx::new_conv_texture(dstWidth, dstHeight, texCopyFmt, "Copy Conv Texture");
} else {
// Configure the texture swizzle to use alpha 1.0 if targeting RGB565 or EFB doesn't have alpha
const auto fmt = texCopyFmt == GX_TF_RGB565 || g_gxState.pixelFmt == GX_PF_RGB8_Z24 ||
g_gxState.pixelFmt == GX_PF_RGB565_Z16
? GX_TF_RGB565
: GX_TF_RGBA8;
handle = aurora::gfx::new_render_texture(dstWidth, dstHeight, fmt, "Resolved Texture");
}
it = g_gxState.copyTextureCache.emplace(key, handle).first;
}
const auto& handle = it->second;
Expand All @@ -167,24 +172,9 @@ void GXCopyTex(void* dest, GXBool clear) {
const auto clearAlpha = clear && g_gxState.alphaUpdate;
const auto clearDepth = clear && g_gxState.depthUpdate;
aurora::gfx::resolve_pass(handle, rect, clearColor, clearAlpha, clearDepth, g_gxState.clearColor,
aurora::gx::clear_depth_value());

if (aurora::gfx::tex_copy_conv::needs_conversion(g_gxState.texCopyFmt)) {
auto convIt = g_gxState.convTextureCache.find(key);
if (convIt == g_gxState.convTextureCache.end()) {
auto convHandle =
aurora::gfx::new_conv_texture(rect.width, rect.height, g_gxState.texCopyFmt, "Copy Conv Texture");
convIt = g_gxState.convTextureCache.emplace(key, convHandle).first;
}
aurora::gfx::queue_copy_conv({
.fmt = g_gxState.texCopyFmt,
.src = handle,
.dst = convIt->second,
});
g_gxState.copyTextures[dest] = convIt->second;
} else {
g_gxState.copyTextures[dest] = handle;
}
aurora::gx::clear_depth_value(), texCopyFmt);

g_gxState.copyTextures[dest] = handle;
}

// TODO GXGetYScaleFactor
Expand Down
14 changes: 6 additions & 8 deletions lib/gfx/clear.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ wgpu::ColorWriteMask clear_write_mask(bool clearColor, bool clearAlpha) {
namespace aurora::gfx::clear {

using webgpu::g_device;
using webgpu::g_frameBuffer;
using webgpu::g_graphicsConfig;

wgpu::RenderPipeline create_pipeline(const PipelineConfig& config) {
Expand Down Expand Up @@ -103,23 +102,22 @@ fn fs_main() -> @location(0) vec4<f32> {
.depthStencil = &depthStencil,
.multisample =
wgpu::MultisampleState{
.count = g_graphicsConfig.msaaSamples,
.mask = UINT32_MAX,
.count = config.msaaSamples,
},
.fragment = &fragmentState,
};
return g_device.CreateRenderPipeline(&pipelineDescriptor);
}

void render(const DrawData& data, const wgpu::RenderPassEncoder& pass) {
void render(const DrawData& data, const wgpu::RenderPassEncoder& pass, const wgpu::Extent3D& targetSize) {
if (!bind_pipeline(data.pipeline, pass)) {
return;
}

const auto& size = g_frameBuffer.size;
pass.SetBlendConstant(&data.color);
pass.SetViewport(0.f, 0.f, static_cast<float>(size.width), static_cast<float>(size.height), data.depth, data.depth);
pass.SetScissorRect(0, 0, size.width, size.height);
pass.SetViewport(0.f, 0.f, static_cast<float>(targetSize.width), static_cast<float>(targetSize.height), data.depth,
data.depth);
pass.SetScissorRect(0, 0, targetSize.width, targetSize.height);
pass.Draw(3);
}
} // namespace aurora::gfx::clear
} // namespace aurora::gfx::clear
17 changes: 9 additions & 8 deletions lib/gfx/clear.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,17 @@ struct DrawData {
float depth = 0.f;
};

constexpr uint8_t ClearPipelineConfigVersion = 1;
constexpr uint32_t ClearPipelineConfigVersion = 2;
struct PipelineConfig {
uint8_t version = ClearPipelineConfigVersion;
bool clearColor : 1 = true;
bool clearAlpha : 1 = true;
bool clearDepth : 1 = true;
uint8_t _pad : 5 = 0;
uint32_t version = ClearPipelineConfigVersion;
uint32_t msaaSamples = 1;
bool clearColor = true;
bool clearAlpha = true;
bool clearDepth = true;
uint8_t _pad = 0;
};
static_assert(std::has_unique_object_representations_v<PipelineConfig>);

wgpu::RenderPipeline create_pipeline(const PipelineConfig& config);
void render(const DrawData& data, const wgpu::RenderPassEncoder& pass);
} // namespace aurora::gfx::clear
void render(const DrawData& data, const wgpu::RenderPassEncoder& pass, const wgpu::Extent3D& targetSize);
} // namespace aurora::gfx::clear
Loading
Loading