Implement GX2SetPolygonOffset

Co-authored-by: Lurs <2795933+Lurs@users.noreply.github.com>

Co-authored-by: Luke Street <luke@street.dev>
This commit is contained in:
SuperDude88
2026-05-22 13:24:56 -04:00
committed by Luke Street
parent 558ba0a987
commit 7ba0d010cc
6 changed files with 66 additions and 8 deletions
+9
View File
@@ -66,6 +66,15 @@ void GXSetScissorRender(u32 left, u32 top, u32 wd, u32 ht) {
GX_WRITE_U32(ht);
}
void GX2SetPolygonOffset(f32 mFrontOffset, f32 mFrontScale, f32 mBackOffset, f32 mBackScale, f32 mClamp) {
GX_WRITE_AURORA(GX2_SET_POLYGON_OFFSET);
GX_WRITE_F32(mFrontOffset);
GX_WRITE_F32(mFrontScale);
GX_WRITE_F32(mBackOffset);
GX_WRITE_F32(mBackScale);
GX_WRITE_F32(mClamp);
}
void GXCreateFrameBuffer(u32 width, u32 height) {
aurora::gx::fifo::drain();
aurora::gfx::begin_offscreen(width, height);
+13
View File
@@ -1765,6 +1765,19 @@ void handle_aurora(const u8* data, u32& pos, u32 size, bool bigEndian) {
pos += 4;
slot.set_no_cache(false); // Reset no-cache flag
g_gxState.stateDirty = true;
} else if (subCmd == GX2_SET_POLYGON_OFFSET) {
CHECK(pos + 20 <= size, "GX2_SET_POLYGON_OFFSET read overrun");
g_gxState.frontOffset = read_f32(data + pos, bigEndian);
pos += 4;
g_gxState.frontScale = read_f32(data + pos, bigEndian);
pos += 4;
g_gxState.backOffset = read_f32(data + pos, bigEndian);
pos += 4;
g_gxState.backScale = read_f32(data + pos, bigEndian);
pos += 4;
g_gxState.clamp = read_f32(data + pos, bigEndian);
pos += 4;
g_gxState.stateDirty = true;
} else if (subCmd == GX_LOAD_AURORA_DESTROY_TEXOBJ) {
CHECK(pos + 4 <= size, "GX_LOAD_AURORA_DESTROY_TEXOBJ read overrun");
evict_texture_object(read_u32(data + pos, bigEndian));
+29 -7
View File
@@ -16,9 +16,12 @@
#include <tracy/Tracy.hpp>
#include <atomic>
#include <bit>
#include <cfloat>
#include <cmath>
#include <mutex>
#include <optional>
#include <utility>
static aurora::Module Log("aurora::gx");
@@ -179,9 +182,8 @@ gfx::TextureHandle resolve_static_texture(const GXTexObj_& obj) {
#else
const auto nameStr = "GX Static Texture";
#endif
handle =
gfx::new_static_texture_2d(obj.width(), obj.height(), obj.mip_count(), obj.format(),
{static_cast<const uint8_t*>(obj.data), UINT32_MAX}, false, nameStr);
handle = gfx::new_static_texture_2d(obj.width(), obj.height(), obj.mip_count(), obj.format(),
{static_cast<const uint8_t*>(obj.data), UINT32_MAX}, false, nameStr);
}
if (!obj.no_cache()) {
store_cached_texture(obj, handle);
@@ -261,6 +263,18 @@ u32 resolved_format_for_handle(const gfx::TextureHandle& handle) {
}
return GX_TF_RGBA8_PC;
}
template <typename T>
T round_away_from_zero(float value) noexcept {
return static_cast<T>(value < 0.0f ? std::floor(value) : std::ceil(value));
}
std::pair<f32, f32> polygon_offset_for_cull_mode(GXCullMode cullMode) noexcept {
if (cullMode == GX_CULL_FRONT) {
return {g_gxState.backOffset, g_gxState.backScale};
}
return {g_gxState.frontOffset, g_gxState.frontScale};
}
} // namespace
Vec2<uint32_t> logical_fb_size() noexcept {
@@ -384,9 +398,7 @@ void clear_copy_texture_cache() noexcept {
}
}
void clear_static_texture_cache() noexcept {
s_staticTextureCacheClearPending.store(true, std::memory_order_release);
}
void clear_static_texture_cache() noexcept { s_staticTextureCacheClearPending.store(true, std::memory_order_release); }
void evict_copy_texture(const void* dest) noexcept {
g_gxState.copyTextures.erase(dest);
@@ -597,10 +609,15 @@ static inline wgpu::PrimitiveState to_primitive_state(GXCullMode gx_cullMode) {
wgpu::RenderPipeline build_pipeline(const PipelineConfig& config, ArrayRef<wgpu::VertexBufferLayout> vtxBuffers,
wgpu::ShaderModule shader, const char* label) noexcept {
ZoneScoped;
const float depthBias = (UseReversedZ ? -1.0f : 1.0f) * std::bit_cast<float>(config.polygonOffsetBits);
const float depthBiasSlopeScale = (UseReversedZ ? -1.0f : 1.0f) * std::bit_cast<float>(config.polygonOffsetScaleBits);
const wgpu::DepthStencilState depthStencil{
.format = g_graphicsConfig.depthFormat,
.depthWriteEnabled = config.depthCompare && config.depthUpdate,
.depthCompare = config.depthCompare ? to_compare_function(config.depthFunc) : wgpu::CompareFunction::Always,
.depthBias = round_away_from_zero<int32_t>(depthBias),
.depthBiasSlopeScale = depthBiasSlopeScale,
.depthBiasClamp = std::bit_cast<float>(config.polygonOffsetClampBits),
};
const auto blendState =
to_blend_state(config.blendMode, config.blendFacSrc, config.blendFacDst, config.blendOp, config.dstAlpha);
@@ -813,16 +830,21 @@ void populate_pipeline_config(PipelineConfig& config, GXPrimitive primitive, GXV
if (g_gxState.alphaCompare) {
config.shaderConfig.alphaCompare = g_gxState.alphaCompare;
}
const auto cullMode = config.shaderConfig.lineMode == 0 ? g_gxState.cullMode : GX_CULL_NONE;
const auto [polygonOffset, polygonOffsetScale] = polygon_offset_for_cull_mode(cullMode);
config = {
.msaaSamples = gfx::get_sample_count(),
.shaderConfig = config.shaderConfig,
.depthFunc = g_gxState.depthFunc,
.cullMode = config.shaderConfig.lineMode == 0 ? g_gxState.cullMode : GX_CULL_NONE,
.cullMode = cullMode,
.blendMode = g_gxState.blendMode,
.blendFacSrc = g_gxState.blendFacSrc,
.blendFacDst = g_gxState.blendFacDst,
.blendOp = g_gxState.blendOp,
.dstAlpha = g_gxState.dstAlpha,
.polygonOffsetBits = std::bit_cast<uint32_t>(polygonOffset),
.polygonOffsetScaleBits = std::bit_cast<uint32_t>(polygonOffsetScale),
.polygonOffsetClampBits = std::bit_cast<uint32_t>(g_gxState.clamp),
.depthCompare = g_gxState.depthCompare,
.depthUpdate = g_gxState.depthUpdate,
.alphaUpdate = g_gxState.alphaUpdate,
+7
View File
@@ -380,6 +380,13 @@ struct GXState {
}();
std::array<u32, 0x1A> xfRegCache;
// GX2 state
f32 frontOffset = 0.0f;
f32 frontScale = 0.0f;
f32 backOffset = 0.0f;
f32 backScale = 0.0f;
f32 clamp = 0.0f;
void clearVtxSizeCache() { lastVtxFmt = GX_MAX_VTXFMT; }
};
extern GXState g_gxState;
+4 -1
View File
@@ -16,7 +16,7 @@ struct DrawData {
uint32_t dstAlpha;
};
constexpr uint32_t GXPipelineConfigVersion = 11;
constexpr uint32_t GXPipelineConfigVersion = 13;
struct PipelineConfig {
uint32_t version = GXPipelineConfigVersion;
uint32_t msaaSamples = 1;
@@ -27,6 +27,9 @@ struct PipelineConfig {
GXBlendFactor blendFacSrc, blendFacDst;
GXLogicOp blendOp;
uint32_t dstAlpha;
uint32_t polygonOffsetBits;
uint32_t polygonOffsetScaleBits;
uint32_t polygonOffsetClampBits;
bool depthCompare, depthUpdate, alphaUpdate, colorUpdate;
};
static_assert(std::has_unique_object_representations_v<PipelineConfig>);