VideoCore: Split framebuffer regs from Regs struct
This commit is contained in:
parent
9017093f58
commit
23713d5dee
11 changed files with 503 additions and 457 deletions
|
@ -183,7 +183,7 @@ void RasterizerOpenGL::DrawTriangles() {
|
|||
CachedSurface* depth_surface;
|
||||
MathUtil::Rectangle<int> rect;
|
||||
std::tie(color_surface, depth_surface, rect) =
|
||||
res_cache.GetFramebufferSurfaces(regs.framebuffer);
|
||||
res_cache.GetFramebufferSurfaces(regs.framebuffer.framebuffer);
|
||||
|
||||
state.draw.draw_framebuffer = framebuffer.handle;
|
||||
state.Apply();
|
||||
|
@ -192,7 +192,8 @@ void RasterizerOpenGL::DrawTriangles() {
|
|||
color_surface != nullptr ? color_surface->texture.handle : 0, 0);
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,
|
||||
depth_surface != nullptr ? depth_surface->texture.handle : 0, 0);
|
||||
bool has_stencil = regs.framebuffer.depth_format == Pica::Regs::DepthFormat::D24S8;
|
||||
bool has_stencil =
|
||||
regs.framebuffer.framebuffer.depth_format == Pica::FramebufferRegs::DepthFormat::D24S8;
|
||||
glFramebufferTexture2D(
|
||||
GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
|
||||
(has_stencil && depth_surface != nullptr) ? depth_surface->texture.handle : 0, 0);
|
||||
|
@ -339,13 +340,13 @@ void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) {
|
|||
break;
|
||||
|
||||
// Blending
|
||||
case PICA_REG_INDEX(output_merger.alphablend_enable):
|
||||
case PICA_REG_INDEX(framebuffer.output_merger.alphablend_enable):
|
||||
SyncBlendEnabled();
|
||||
break;
|
||||
case PICA_REG_INDEX(output_merger.alpha_blending):
|
||||
case PICA_REG_INDEX(framebuffer.output_merger.alpha_blending):
|
||||
SyncBlendFuncs();
|
||||
break;
|
||||
case PICA_REG_INDEX(output_merger.blend_const):
|
||||
case PICA_REG_INDEX(framebuffer.output_merger.blend_const):
|
||||
SyncBlendColor();
|
||||
break;
|
||||
|
||||
|
@ -365,25 +366,25 @@ void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) {
|
|||
break;
|
||||
|
||||
// Alpha test
|
||||
case PICA_REG_INDEX(output_merger.alpha_test):
|
||||
case PICA_REG_INDEX(framebuffer.output_merger.alpha_test):
|
||||
SyncAlphaTest();
|
||||
shader_dirty = true;
|
||||
break;
|
||||
|
||||
// Sync GL stencil test + stencil write mask
|
||||
// (Pica stencil test function register also contains a stencil write mask)
|
||||
case PICA_REG_INDEX(output_merger.stencil_test.raw_func):
|
||||
case PICA_REG_INDEX(framebuffer.output_merger.stencil_test.raw_func):
|
||||
SyncStencilTest();
|
||||
SyncStencilWriteMask();
|
||||
break;
|
||||
case PICA_REG_INDEX(output_merger.stencil_test.raw_op):
|
||||
case PICA_REG_INDEX(framebuffer.depth_format):
|
||||
case PICA_REG_INDEX(framebuffer.output_merger.stencil_test.raw_op):
|
||||
case PICA_REG_INDEX(framebuffer.framebuffer.depth_format):
|
||||
SyncStencilTest();
|
||||
break;
|
||||
|
||||
// Sync GL depth test + depth and color write mask
|
||||
// (Pica depth test function register also contains a depth and color write mask)
|
||||
case PICA_REG_INDEX(output_merger.depth_test_enable):
|
||||
case PICA_REG_INDEX(framebuffer.output_merger.depth_test_enable):
|
||||
SyncDepthTest();
|
||||
SyncDepthWriteMask();
|
||||
SyncColorWriteMask();
|
||||
|
@ -391,14 +392,14 @@ void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) {
|
|||
|
||||
// Sync GL depth and stencil write mask
|
||||
// (This is a dedicated combined depth / stencil write-enable register)
|
||||
case PICA_REG_INDEX(framebuffer.allow_depth_stencil_write):
|
||||
case PICA_REG_INDEX(framebuffer.framebuffer.allow_depth_stencil_write):
|
||||
SyncDepthWriteMask();
|
||||
SyncStencilWriteMask();
|
||||
break;
|
||||
|
||||
// Sync GL color write mask
|
||||
// (This is a dedicated color write-enable register)
|
||||
case PICA_REG_INDEX(framebuffer.allow_color_write):
|
||||
case PICA_REG_INDEX(framebuffer.framebuffer.allow_color_write):
|
||||
SyncColorWriteMask();
|
||||
break;
|
||||
|
||||
|
@ -408,7 +409,7 @@ void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) {
|
|||
break;
|
||||
|
||||
// Logic op
|
||||
case PICA_REG_INDEX(output_merger.logic_op):
|
||||
case PICA_REG_INDEX(framebuffer.output_merger.logic_op):
|
||||
SyncLogicOp();
|
||||
break;
|
||||
|
||||
|
@ -1158,25 +1159,28 @@ void RasterizerOpenGL::SyncDepthOffset() {
|
|||
}
|
||||
|
||||
void RasterizerOpenGL::SyncBlendEnabled() {
|
||||
state.blend.enabled = (Pica::g_state.regs.output_merger.alphablend_enable == 1);
|
||||
state.blend.enabled = (Pica::g_state.regs.framebuffer.output_merger.alphablend_enable == 1);
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SyncBlendFuncs() {
|
||||
const auto& regs = Pica::g_state.regs;
|
||||
state.blend.rgb_equation =
|
||||
PicaToGL::BlendEquation(regs.output_merger.alpha_blending.blend_equation_rgb);
|
||||
PicaToGL::BlendEquation(regs.framebuffer.output_merger.alpha_blending.blend_equation_rgb);
|
||||
state.blend.a_equation =
|
||||
PicaToGL::BlendEquation(regs.output_merger.alpha_blending.blend_equation_a);
|
||||
PicaToGL::BlendEquation(regs.framebuffer.output_merger.alpha_blending.blend_equation_a);
|
||||
state.blend.src_rgb_func =
|
||||
PicaToGL::BlendFunc(regs.output_merger.alpha_blending.factor_source_rgb);
|
||||
PicaToGL::BlendFunc(regs.framebuffer.output_merger.alpha_blending.factor_source_rgb);
|
||||
state.blend.dst_rgb_func =
|
||||
PicaToGL::BlendFunc(regs.output_merger.alpha_blending.factor_dest_rgb);
|
||||
state.blend.src_a_func = PicaToGL::BlendFunc(regs.output_merger.alpha_blending.factor_source_a);
|
||||
state.blend.dst_a_func = PicaToGL::BlendFunc(regs.output_merger.alpha_blending.factor_dest_a);
|
||||
PicaToGL::BlendFunc(regs.framebuffer.output_merger.alpha_blending.factor_dest_rgb);
|
||||
state.blend.src_a_func =
|
||||
PicaToGL::BlendFunc(regs.framebuffer.output_merger.alpha_blending.factor_source_a);
|
||||
state.blend.dst_a_func =
|
||||
PicaToGL::BlendFunc(regs.framebuffer.output_merger.alpha_blending.factor_dest_a);
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SyncBlendColor() {
|
||||
auto blend_color = PicaToGL::ColorRGBA8(Pica::g_state.regs.output_merger.blend_const.raw);
|
||||
auto blend_color =
|
||||
PicaToGL::ColorRGBA8(Pica::g_state.regs.framebuffer.output_merger.blend_const.raw);
|
||||
state.blend.color.red = blend_color[0];
|
||||
state.blend.color.green = blend_color[1];
|
||||
state.blend.color.blue = blend_color[2];
|
||||
|
@ -1208,66 +1212,73 @@ void RasterizerOpenGL::SyncFogLUT() {
|
|||
|
||||
void RasterizerOpenGL::SyncAlphaTest() {
|
||||
const auto& regs = Pica::g_state.regs;
|
||||
if (regs.output_merger.alpha_test.ref != uniform_block_data.data.alphatest_ref) {
|
||||
uniform_block_data.data.alphatest_ref = regs.output_merger.alpha_test.ref;
|
||||
if (regs.framebuffer.output_merger.alpha_test.ref != uniform_block_data.data.alphatest_ref) {
|
||||
uniform_block_data.data.alphatest_ref = regs.framebuffer.output_merger.alpha_test.ref;
|
||||
uniform_block_data.dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SyncLogicOp() {
|
||||
state.logic_op = PicaToGL::LogicOp(Pica::g_state.regs.output_merger.logic_op);
|
||||
state.logic_op = PicaToGL::LogicOp(Pica::g_state.regs.framebuffer.output_merger.logic_op);
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SyncColorWriteMask() {
|
||||
const auto& regs = Pica::g_state.regs;
|
||||
|
||||
auto IsColorWriteEnabled = [&](u32 value) {
|
||||
return (regs.framebuffer.allow_color_write != 0 && value != 0) ? GL_TRUE : GL_FALSE;
|
||||
return (regs.framebuffer.framebuffer.allow_color_write != 0 && value != 0) ? GL_TRUE
|
||||
: GL_FALSE;
|
||||
};
|
||||
|
||||
state.color_mask.red_enabled = IsColorWriteEnabled(regs.output_merger.red_enable);
|
||||
state.color_mask.green_enabled = IsColorWriteEnabled(regs.output_merger.green_enable);
|
||||
state.color_mask.blue_enabled = IsColorWriteEnabled(regs.output_merger.blue_enable);
|
||||
state.color_mask.alpha_enabled = IsColorWriteEnabled(regs.output_merger.alpha_enable);
|
||||
state.color_mask.red_enabled = IsColorWriteEnabled(regs.framebuffer.output_merger.red_enable);
|
||||
state.color_mask.green_enabled =
|
||||
IsColorWriteEnabled(regs.framebuffer.output_merger.green_enable);
|
||||
state.color_mask.blue_enabled = IsColorWriteEnabled(regs.framebuffer.output_merger.blue_enable);
|
||||
state.color_mask.alpha_enabled =
|
||||
IsColorWriteEnabled(regs.framebuffer.output_merger.alpha_enable);
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SyncStencilWriteMask() {
|
||||
const auto& regs = Pica::g_state.regs;
|
||||
state.stencil.write_mask = (regs.framebuffer.allow_depth_stencil_write != 0)
|
||||
? static_cast<GLuint>(regs.output_merger.stencil_test.write_mask)
|
||||
: 0;
|
||||
state.stencil.write_mask =
|
||||
(regs.framebuffer.framebuffer.allow_depth_stencil_write != 0)
|
||||
? static_cast<GLuint>(regs.framebuffer.output_merger.stencil_test.write_mask)
|
||||
: 0;
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SyncDepthWriteMask() {
|
||||
const auto& regs = Pica::g_state.regs;
|
||||
state.depth.write_mask =
|
||||
(regs.framebuffer.allow_depth_stencil_write != 0 && regs.output_merger.depth_write_enable)
|
||||
? GL_TRUE
|
||||
: GL_FALSE;
|
||||
state.depth.write_mask = (regs.framebuffer.framebuffer.allow_depth_stencil_write != 0 &&
|
||||
regs.framebuffer.output_merger.depth_write_enable)
|
||||
? GL_TRUE
|
||||
: GL_FALSE;
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SyncStencilTest() {
|
||||
const auto& regs = Pica::g_state.regs;
|
||||
state.stencil.test_enabled = regs.output_merger.stencil_test.enable &&
|
||||
regs.framebuffer.depth_format == Pica::Regs::DepthFormat::D24S8;
|
||||
state.stencil.test_func = PicaToGL::CompareFunc(regs.output_merger.stencil_test.func);
|
||||
state.stencil.test_ref = regs.output_merger.stencil_test.reference_value;
|
||||
state.stencil.test_mask = regs.output_merger.stencil_test.input_mask;
|
||||
state.stencil.test_enabled =
|
||||
regs.framebuffer.output_merger.stencil_test.enable &&
|
||||
regs.framebuffer.framebuffer.depth_format == Pica::FramebufferRegs::DepthFormat::D24S8;
|
||||
state.stencil.test_func =
|
||||
PicaToGL::CompareFunc(regs.framebuffer.output_merger.stencil_test.func);
|
||||
state.stencil.test_ref = regs.framebuffer.output_merger.stencil_test.reference_value;
|
||||
state.stencil.test_mask = regs.framebuffer.output_merger.stencil_test.input_mask;
|
||||
state.stencil.action_stencil_fail =
|
||||
PicaToGL::StencilOp(regs.output_merger.stencil_test.action_stencil_fail);
|
||||
PicaToGL::StencilOp(regs.framebuffer.output_merger.stencil_test.action_stencil_fail);
|
||||
state.stencil.action_depth_fail =
|
||||
PicaToGL::StencilOp(regs.output_merger.stencil_test.action_depth_fail);
|
||||
PicaToGL::StencilOp(regs.framebuffer.output_merger.stencil_test.action_depth_fail);
|
||||
state.stencil.action_depth_pass =
|
||||
PicaToGL::StencilOp(regs.output_merger.stencil_test.action_depth_pass);
|
||||
PicaToGL::StencilOp(regs.framebuffer.output_merger.stencil_test.action_depth_pass);
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SyncDepthTest() {
|
||||
const auto& regs = Pica::g_state.regs;
|
||||
state.depth.test_enabled =
|
||||
regs.output_merger.depth_test_enable == 1 || regs.output_merger.depth_write_enable == 1;
|
||||
state.depth.test_func = regs.output_merger.depth_test_enable == 1
|
||||
? PicaToGL::CompareFunc(regs.output_merger.depth_test_func)
|
||||
: GL_ALWAYS;
|
||||
state.depth.test_enabled = regs.framebuffer.output_merger.depth_test_enable == 1 ||
|
||||
regs.framebuffer.output_merger.depth_write_enable == 1;
|
||||
state.depth.test_func =
|
||||
regs.framebuffer.output_merger.depth_test_enable == 1
|
||||
? PicaToGL::CompareFunc(regs.framebuffer.output_merger.depth_test_func)
|
||||
: GL_ALWAYS;
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SyncCombinerColor() {
|
||||
|
|
|
@ -56,9 +56,9 @@ union PicaShaderConfig {
|
|||
|
||||
state.depthmap_enable = regs.rasterizer.depthmap_enable;
|
||||
|
||||
state.alpha_test_func = regs.output_merger.alpha_test.enable
|
||||
? regs.output_merger.alpha_test.func.Value()
|
||||
: Pica::Regs::CompareFunc::Always;
|
||||
state.alpha_test_func = regs.framebuffer.output_merger.alpha_test.enable
|
||||
? regs.framebuffer.output_merger.alpha_test.func.Value()
|
||||
: Pica::FramebufferRegs::CompareFunc::Always;
|
||||
|
||||
state.texture0_type = regs.texturing.texture0.type;
|
||||
|
||||
|
@ -172,7 +172,7 @@ union PicaShaderConfig {
|
|||
};
|
||||
|
||||
struct State {
|
||||
Pica::Regs::CompareFunc alpha_test_func;
|
||||
Pica::FramebufferRegs::CompareFunc alpha_test_func;
|
||||
Pica::RasterizerRegs::ScissorMode scissor_test_mode;
|
||||
Pica::TexturingRegs::TextureConfig::TextureType texture0_type;
|
||||
std::array<TevStageConfigRaw, 6> tev_stages;
|
||||
|
|
|
@ -525,7 +525,9 @@ CachedSurface* RasterizerCacheOpenGL::GetTextureSurface(
|
|||
}
|
||||
|
||||
std::tuple<CachedSurface*, CachedSurface*, MathUtil::Rectangle<int>>
|
||||
RasterizerCacheOpenGL::GetFramebufferSurfaces(const Pica::Regs::FramebufferConfig& config) {
|
||||
RasterizerCacheOpenGL::GetFramebufferSurfaces(
|
||||
const Pica::FramebufferRegs::FramebufferConfig& config) {
|
||||
|
||||
const auto& regs = Pica::g_state.regs;
|
||||
|
||||
// Make sur that framebuffers don't overlap if both color and depth are being used
|
||||
|
@ -537,11 +539,12 @@ RasterizerCacheOpenGL::GetFramebufferSurfaces(const Pica::Regs::FramebufferConfi
|
|||
config.GetColorBufferPhysicalAddress(),
|
||||
fb_area * GPU::Regs::BytesPerPixel(GPU::Regs::PixelFormat(config.color_format.Value())),
|
||||
config.GetDepthBufferPhysicalAddress(),
|
||||
fb_area * Pica::Regs::BytesPerDepthPixel(config.depth_format));
|
||||
fb_area * Pica::FramebufferRegs::BytesPerDepthPixel(config.depth_format));
|
||||
bool using_color_fb = config.GetColorBufferPhysicalAddress() != 0;
|
||||
bool using_depth_fb = config.GetDepthBufferPhysicalAddress() != 0 &&
|
||||
(regs.output_merger.depth_test_enable ||
|
||||
regs.output_merger.depth_write_enable || !framebuffers_overlap);
|
||||
bool using_depth_fb =
|
||||
config.GetDepthBufferPhysicalAddress() != 0 &&
|
||||
(regs.framebuffer.output_merger.depth_test_enable ||
|
||||
regs.framebuffer.output_merger.depth_write_enable || !framebuffers_overlap);
|
||||
|
||||
if (framebuffers_overlap && using_color_fb && using_depth_fb) {
|
||||
LOG_CRITICAL(Render_OpenGL, "Color and depth framebuffer memory regions overlap; "
|
||||
|
|
|
@ -100,11 +100,11 @@ struct CachedSurface {
|
|||
return ((unsigned int)format < 14) ? (PixelFormat)format : PixelFormat::Invalid;
|
||||
}
|
||||
|
||||
static PixelFormat PixelFormatFromColorFormat(Pica::Regs::ColorFormat format) {
|
||||
static PixelFormat PixelFormatFromColorFormat(Pica::FramebufferRegs::ColorFormat format) {
|
||||
return ((unsigned int)format < 5) ? (PixelFormat)format : PixelFormat::Invalid;
|
||||
}
|
||||
|
||||
static PixelFormat PixelFormatFromDepthFormat(Pica::Regs::DepthFormat format) {
|
||||
static PixelFormat PixelFormatFromDepthFormat(Pica::FramebufferRegs::DepthFormat format) {
|
||||
return ((unsigned int)format < 4) ? (PixelFormat)((unsigned int)format + 14)
|
||||
: PixelFormat::Invalid;
|
||||
}
|
||||
|
@ -217,7 +217,7 @@ public:
|
|||
/// Gets the color and depth surfaces and rect (resolution scaled) based on the framebuffer
|
||||
/// configuration
|
||||
std::tuple<CachedSurface*, CachedSurface*, MathUtil::Rectangle<int>> GetFramebufferSurfaces(
|
||||
const Pica::Regs::FramebufferConfig& config);
|
||||
const Pica::FramebufferRegs::FramebufferConfig& config);
|
||||
|
||||
/// Attempt to get a surface that exactly matches the fill region and format
|
||||
CachedSurface* TryGetFillSurface(const GPU::Regs::MemoryFillConfig& config);
|
||||
|
|
|
@ -277,8 +277,8 @@ static void AppendAlphaCombiner(std::string& out, TevStageConfig::Operation oper
|
|||
}
|
||||
|
||||
/// Writes the if-statement condition used to evaluate alpha testing
|
||||
static void AppendAlphaTestCondition(std::string& out, Regs::CompareFunc func) {
|
||||
using CompareFunc = Regs::CompareFunc;
|
||||
static void AppendAlphaTestCondition(std::string& out, Pica::FramebufferRegs::CompareFunc func) {
|
||||
using CompareFunc = Pica::FramebufferRegs::CompareFunc;
|
||||
switch (func) {
|
||||
case CompareFunc::Never:
|
||||
out += "true";
|
||||
|
@ -634,7 +634,7 @@ vec4 secondary_fragment_color = vec4(0.0);
|
|||
)";
|
||||
|
||||
// Do not do any sort of processing if it's obvious we're not going to pass the alpha test
|
||||
if (state.alpha_test_func == Regs::CompareFunc::Never) {
|
||||
if (state.alpha_test_func == Pica::FramebufferRegs::CompareFunc::Never) {
|
||||
out += "discard; }";
|
||||
return out;
|
||||
}
|
||||
|
@ -667,7 +667,7 @@ vec4 secondary_fragment_color = vec4(0.0);
|
|||
for (size_t index = 0; index < state.tev_stages.size(); ++index)
|
||||
WriteTevStage(out, config, (unsigned)index);
|
||||
|
||||
if (state.alpha_test_func != Regs::CompareFunc::Always) {
|
||||
if (state.alpha_test_func != Pica::FramebufferRegs::CompareFunc::Always) {
|
||||
out += "if (";
|
||||
AppendAlphaTestCondition(out, state.alpha_test_func);
|
||||
out += ") discard;\n";
|
||||
|
|
|
@ -76,7 +76,7 @@ inline GLenum WrapMode(Pica::TexturingRegs::TextureConfig::WrapMode mode) {
|
|||
return gl_mode;
|
||||
}
|
||||
|
||||
inline GLenum BlendEquation(Pica::Regs::BlendEquation equation) {
|
||||
inline GLenum BlendEquation(Pica::FramebufferRegs::BlendEquation equation) {
|
||||
static const GLenum blend_equation_table[] = {
|
||||
GL_FUNC_ADD, // BlendEquation::Add
|
||||
GL_FUNC_SUBTRACT, // BlendEquation::Subtract
|
||||
|
@ -96,7 +96,7 @@ inline GLenum BlendEquation(Pica::Regs::BlendEquation equation) {
|
|||
return blend_equation_table[(unsigned)equation];
|
||||
}
|
||||
|
||||
inline GLenum BlendFunc(Pica::Regs::BlendFactor factor) {
|
||||
inline GLenum BlendFunc(Pica::FramebufferRegs::BlendFactor factor) {
|
||||
static const GLenum blend_func_table[] = {
|
||||
GL_ZERO, // BlendFactor::Zero
|
||||
GL_ONE, // BlendFactor::One
|
||||
|
@ -126,7 +126,7 @@ inline GLenum BlendFunc(Pica::Regs::BlendFactor factor) {
|
|||
return blend_func_table[(unsigned)factor];
|
||||
}
|
||||
|
||||
inline GLenum LogicOp(Pica::Regs::LogicOp op) {
|
||||
inline GLenum LogicOp(Pica::FramebufferRegs::LogicOp op) {
|
||||
static const GLenum logic_op_table[] = {
|
||||
GL_CLEAR, // Clear
|
||||
GL_AND, // And
|
||||
|
@ -157,7 +157,7 @@ inline GLenum LogicOp(Pica::Regs::LogicOp op) {
|
|||
return logic_op_table[(unsigned)op];
|
||||
}
|
||||
|
||||
inline GLenum CompareFunc(Pica::Regs::CompareFunc func) {
|
||||
inline GLenum CompareFunc(Pica::FramebufferRegs::CompareFunc func) {
|
||||
static const GLenum compare_func_table[] = {
|
||||
GL_NEVER, // CompareFunc::Never
|
||||
GL_ALWAYS, // CompareFunc::Always
|
||||
|
@ -180,7 +180,7 @@ inline GLenum CompareFunc(Pica::Regs::CompareFunc func) {
|
|||
return compare_func_table[(unsigned)func];
|
||||
}
|
||||
|
||||
inline GLenum StencilOp(Pica::Regs::StencilAction action) {
|
||||
inline GLenum StencilOp(Pica::FramebufferRegs::StencilAction action) {
|
||||
static const GLenum stencil_op_table[] = {
|
||||
GL_KEEP, // StencilAction::Keep
|
||||
GL_ZERO, // StencilAction::Zero
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue