mirror of
https://github.com/encounter/aurora.git
synced 2026-07-09 18:19:33 -07:00
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:
@@ -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);
|
||||
|
||||
@@ -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
@@ -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,
|
||||
|
||||
@@ -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
@@ -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>);
|
||||
|
||||
Reference in New Issue
Block a user