Update 3D regs
This commit is contained in:
parent
61883d8820
commit
752659aef3
29 changed files with 4036 additions and 2105 deletions
|
@ -73,8 +73,8 @@ GLenum AssemblyStage(size_t stage_index) {
|
|||
/// @param location Hardware location
|
||||
/// @return Pair of ARB_transform_feedback3 token stream first and third arguments
|
||||
/// @note Read https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_transform_feedback3.txt
|
||||
std::pair<GLint, GLint> TransformFeedbackEnum(u8 location) {
|
||||
const u8 index = location / 4;
|
||||
std::pair<GLint, GLint> TransformFeedbackEnum(u32 location) {
|
||||
const auto index = location / 4;
|
||||
if (index >= 8 && index <= 39) {
|
||||
return {GL_GENERIC_ATTRIB_NV, index - 8};
|
||||
}
|
||||
|
@ -286,7 +286,7 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
|
|||
buffer_cache.runtime.SetEnableStorageBuffers(use_storage_buffers);
|
||||
|
||||
const auto& regs{maxwell3d->regs};
|
||||
const bool via_header_index{regs.sampler_index == Maxwell::SamplerIndex::ViaHeaderIndex};
|
||||
const bool via_header_index{regs.sampler_binding == Maxwell::SamplerBinding::ViaHeaderBinding};
|
||||
const auto config_stage{[&](size_t stage) LAMBDA_FORCEINLINE {
|
||||
const Shader::Info& info{stage_infos[stage]};
|
||||
buffer_cache.UnbindGraphicsStorageBuffers(stage);
|
||||
|
@ -557,10 +557,25 @@ void GraphicsPipeline::GenerateTransformFeedbackState() {
|
|||
++current_stream;
|
||||
|
||||
const auto& locations = key.xfb_state.varyings[feedback];
|
||||
std::optional<u8> current_index;
|
||||
std::optional<u32> current_index;
|
||||
for (u32 offset = 0; offset < layout.varying_count; ++offset) {
|
||||
const u8 location = locations[offset];
|
||||
const u8 index = location / 4;
|
||||
const auto get_attribute = [&locations](u32 index) -> u32 {
|
||||
switch (index % 4) {
|
||||
case 0:
|
||||
return locations[index / 4].attribute0.Value();
|
||||
case 1:
|
||||
return locations[index / 4].attribute1.Value();
|
||||
case 2:
|
||||
return locations[index / 4].attribute2.Value();
|
||||
case 3:
|
||||
return locations[index / 4].attribute3.Value();
|
||||
}
|
||||
UNREACHABLE();
|
||||
return 0;
|
||||
};
|
||||
|
||||
const auto attribute{get_attribute(offset)};
|
||||
const auto index = attribute / 4U;
|
||||
|
||||
if (current_index == index) {
|
||||
// Increase number of components of the previous attachment
|
||||
|
@ -569,7 +584,7 @@ void GraphicsPipeline::GenerateTransformFeedbackState() {
|
|||
}
|
||||
current_index = index;
|
||||
|
||||
std::tie(cursor[0], cursor[2]) = TransformFeedbackEnum(location);
|
||||
std::tie(cursor[0], cursor[2]) = TransformFeedbackEnum(attribute);
|
||||
cursor[1] = 1;
|
||||
cursor += XFB_ENTRY_STRIDE;
|
||||
}
|
||||
|
|
|
@ -37,8 +37,8 @@ struct GraphicsPipelineKey {
|
|||
BitField<0, 1, u32> xfb_enabled;
|
||||
BitField<1, 1, u32> early_z;
|
||||
BitField<2, 4, Maxwell::PrimitiveTopology> gs_input_topology;
|
||||
BitField<6, 2, Maxwell::TessellationPrimitive> tessellation_primitive;
|
||||
BitField<8, 2, Maxwell::TessellationSpacing> tessellation_spacing;
|
||||
BitField<6, 2, Maxwell::Tessellation::DomainType> tessellation_primitive;
|
||||
BitField<8, 2, Maxwell::Tessellation::Spacing> tessellation_spacing;
|
||||
BitField<10, 1, u32> tessellation_clockwise;
|
||||
};
|
||||
std::array<u32, 3> padding;
|
||||
|
|
|
@ -87,7 +87,7 @@ void RasterizerOpenGL::SyncVertexFormats() {
|
|||
}
|
||||
flags[Dirty::VertexFormat0 + index] = false;
|
||||
|
||||
const auto attrib = maxwell3d->regs.vertex_attrib_format[index];
|
||||
const auto& attrib = maxwell3d->regs.vertex_attrib_format[index];
|
||||
const auto gl_index = static_cast<GLuint>(index);
|
||||
|
||||
// Disable constant attributes.
|
||||
|
@ -97,8 +97,8 @@ void RasterizerOpenGL::SyncVertexFormats() {
|
|||
}
|
||||
glEnableVertexAttribArray(gl_index);
|
||||
|
||||
if (attrib.type == Maxwell::VertexAttribute::Type::SignedInt ||
|
||||
attrib.type == Maxwell::VertexAttribute::Type::UnsignedInt) {
|
||||
if (attrib.type == Maxwell::VertexAttribute::Type::SInt ||
|
||||
attrib.type == Maxwell::VertexAttribute::Type::UInt) {
|
||||
glVertexAttribIFormat(gl_index, attrib.ComponentCount(),
|
||||
MaxwellToGL::VertexFormat(attrib), attrib.offset);
|
||||
} else {
|
||||
|
@ -125,8 +125,8 @@ void RasterizerOpenGL::SyncVertexInstances() {
|
|||
flags[Dirty::VertexInstance0 + index] = false;
|
||||
|
||||
const auto gl_index = static_cast<GLuint>(index);
|
||||
const bool instancing_enabled = regs.instanced_arrays.IsInstancingEnabled(gl_index);
|
||||
const GLuint divisor = instancing_enabled ? regs.vertex_array[index].divisor : 0;
|
||||
const bool instancing_enabled = regs.vertex_stream_instances.IsInstancingEnabled(gl_index);
|
||||
const GLuint divisor = instancing_enabled ? regs.vertex_streams[index].frequency : 0;
|
||||
glVertexBindingDivisor(gl_index, divisor);
|
||||
}
|
||||
}
|
||||
|
@ -147,27 +147,27 @@ void RasterizerOpenGL::Clear() {
|
|||
bool use_depth{};
|
||||
bool use_stencil{};
|
||||
|
||||
if (regs.clear_buffers.R || regs.clear_buffers.G || regs.clear_buffers.B ||
|
||||
regs.clear_buffers.A) {
|
||||
if (regs.clear_surface.R || regs.clear_surface.G || regs.clear_surface.B ||
|
||||
regs.clear_surface.A) {
|
||||
use_color = true;
|
||||
|
||||
const GLuint index = regs.clear_buffers.RT;
|
||||
const GLuint index = regs.clear_surface.RT;
|
||||
state_tracker.NotifyColorMask(index);
|
||||
glColorMaski(index, regs.clear_buffers.R != 0, regs.clear_buffers.G != 0,
|
||||
regs.clear_buffers.B != 0, regs.clear_buffers.A != 0);
|
||||
glColorMaski(index, regs.clear_surface.R != 0, regs.clear_surface.G != 0,
|
||||
regs.clear_surface.B != 0, regs.clear_surface.A != 0);
|
||||
|
||||
// TODO(Rodrigo): Determine if clamping is used on clears
|
||||
SyncFragmentColorClampState();
|
||||
SyncFramebufferSRGB();
|
||||
}
|
||||
if (regs.clear_buffers.Z) {
|
||||
if (regs.clear_surface.Z) {
|
||||
ASSERT_MSG(regs.zeta_enable != 0, "Tried to clear Z but buffer is not enabled!");
|
||||
use_depth = true;
|
||||
|
||||
state_tracker.NotifyDepthMask();
|
||||
glDepthMask(GL_TRUE);
|
||||
}
|
||||
if (regs.clear_buffers.S) {
|
||||
if (regs.clear_surface.S) {
|
||||
ASSERT_MSG(regs.zeta_enable, "Tried to clear stencil but buffer is not enabled!");
|
||||
use_stencil = true;
|
||||
}
|
||||
|
@ -184,16 +184,16 @@ void RasterizerOpenGL::Clear() {
|
|||
texture_cache.UpdateRenderTargets(true);
|
||||
state_tracker.BindFramebuffer(texture_cache.GetFramebuffer()->Handle());
|
||||
SyncViewport();
|
||||
if (regs.clear_flags.scissor) {
|
||||
if (regs.clear_control.use_scissor) {
|
||||
SyncScissorTest();
|
||||
} else {
|
||||
state_tracker.NotifyScissor0();
|
||||
glDisablei(GL_SCISSOR_TEST, 0);
|
||||
}
|
||||
UNIMPLEMENTED_IF(regs.clear_flags.viewport);
|
||||
UNIMPLEMENTED_IF(regs.clear_control.use_viewport_clip0);
|
||||
|
||||
if (use_color) {
|
||||
glClearBufferfv(GL_COLOR, regs.clear_buffers.RT, regs.clear_color);
|
||||
glClearBufferfv(GL_COLOR, regs.clear_surface.RT, regs.clear_color.data());
|
||||
}
|
||||
if (use_depth && use_stencil) {
|
||||
glClearBufferfi(GL_DEPTH_STENCIL, 0, regs.clear_depth, regs.clear_stencil);
|
||||
|
@ -227,14 +227,14 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
|
|||
const GLenum primitive_mode = MaxwellToGL::PrimitiveTopology(maxwell3d->regs.draw.topology);
|
||||
BeginTransformFeedback(pipeline, primitive_mode);
|
||||
|
||||
const GLuint base_instance = static_cast<GLuint>(maxwell3d->regs.vb_base_instance);
|
||||
const GLuint base_instance = static_cast<GLuint>(maxwell3d->regs.global_base_instance_index);
|
||||
const GLsizei num_instances =
|
||||
static_cast<GLsizei>(is_instanced ? maxwell3d->mme_draw.instance_count : 1);
|
||||
if (is_indexed) {
|
||||
const GLint base_vertex = static_cast<GLint>(maxwell3d->regs.vb_element_base);
|
||||
const GLsizei num_vertices = static_cast<GLsizei>(maxwell3d->regs.index_array.count);
|
||||
const GLint base_vertex = static_cast<GLint>(maxwell3d->regs.global_base_vertex_index);
|
||||
const GLsizei num_vertices = static_cast<GLsizei>(maxwell3d->regs.index_buffer.count);
|
||||
const GLvoid* const offset = buffer_cache_runtime.IndexOffset();
|
||||
const GLenum format = MaxwellToGL::IndexFormat(maxwell3d->regs.index_array.format);
|
||||
const GLenum format = MaxwellToGL::IndexFormat(maxwell3d->regs.index_buffer.format);
|
||||
if (num_instances == 1 && base_instance == 0 && base_vertex == 0) {
|
||||
glDrawElements(primitive_mode, num_vertices, format, offset);
|
||||
} else if (num_instances == 1 && base_instance == 0) {
|
||||
|
@ -555,9 +555,9 @@ void RasterizerOpenGL::SyncViewport() {
|
|||
if (dirty_viewport || dirty_clip_control || flags[Dirty::FrontFace]) {
|
||||
flags[Dirty::FrontFace] = false;
|
||||
|
||||
GLenum mode = MaxwellToGL::FrontFace(regs.front_face);
|
||||
GLenum mode = MaxwellToGL::FrontFace(regs.gl_front_face);
|
||||
bool flip_faces = true;
|
||||
if (regs.screen_y_control.triangle_rast_flip != 0) {
|
||||
if (regs.window_origin.flip_y != 0) {
|
||||
flip_faces = !flip_faces;
|
||||
}
|
||||
if (regs.viewport_transform[0].scale_y < 0.0f) {
|
||||
|
@ -582,14 +582,15 @@ void RasterizerOpenGL::SyncViewport() {
|
|||
if (regs.viewport_transform[0].scale_y < 0.0f) {
|
||||
flip_y = !flip_y;
|
||||
}
|
||||
if (regs.screen_y_control.y_negate != 0) {
|
||||
const bool lower_left{regs.window_origin.mode != Maxwell::WindowOrigin::Mode::UpperLeft};
|
||||
if (lower_left) {
|
||||
flip_y = !flip_y;
|
||||
}
|
||||
const bool is_zero_to_one = regs.depth_mode == Maxwell::DepthMode::ZeroToOne;
|
||||
const GLenum origin = flip_y ? GL_UPPER_LEFT : GL_LOWER_LEFT;
|
||||
const GLenum depth = is_zero_to_one ? GL_ZERO_TO_ONE : GL_NEGATIVE_ONE_TO_ONE;
|
||||
state_tracker.ClipControl(origin, depth);
|
||||
state_tracker.SetYNegate(regs.screen_y_control.y_negate != 0);
|
||||
state_tracker.SetYNegate(lower_left);
|
||||
}
|
||||
const bool is_rescaling{texture_cache.IsRescaling()};
|
||||
const float scale = is_rescaling ? Settings::values.resolution_info.up_factor : 1.0f;
|
||||
|
@ -657,7 +658,8 @@ void RasterizerOpenGL::SyncDepthClamp() {
|
|||
}
|
||||
flags[Dirty::DepthClampEnabled] = false;
|
||||
|
||||
oglEnable(GL_DEPTH_CLAMP, maxwell3d->regs.view_volume_clip_control.depth_clamp_disabled == 0);
|
||||
oglEnable(GL_DEPTH_CLAMP, maxwell3d->regs.viewport_clip_control.geometry_clip !=
|
||||
Maxwell::ViewportClipControl::GeometryClip::Passthrough);
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SyncClipEnabled(u32 clip_mask) {
|
||||
|
@ -667,7 +669,7 @@ void RasterizerOpenGL::SyncClipEnabled(u32 clip_mask) {
|
|||
}
|
||||
flags[Dirty::ClipDistances] = false;
|
||||
|
||||
clip_mask &= maxwell3d->regs.clip_distance_enabled;
|
||||
clip_mask &= maxwell3d->regs.user_clip_enable.raw;
|
||||
if (clip_mask == last_clip_distance_mask) {
|
||||
return;
|
||||
}
|
||||
|
@ -689,9 +691,9 @@ void RasterizerOpenGL::SyncCullMode() {
|
|||
if (flags[Dirty::CullTest]) {
|
||||
flags[Dirty::CullTest] = false;
|
||||
|
||||
if (regs.cull_test_enabled) {
|
||||
if (regs.gl_cull_test_enabled) {
|
||||
glEnable(GL_CULL_FACE);
|
||||
glCullFace(MaxwellToGL::CullFace(regs.cull_face));
|
||||
glCullFace(MaxwellToGL::CullFace(regs.gl_cull_face));
|
||||
} else {
|
||||
glDisable(GL_CULL_FACE);
|
||||
}
|
||||
|
@ -743,20 +745,20 @@ void RasterizerOpenGL::SyncStencilTestState() {
|
|||
const auto& regs = maxwell3d->regs;
|
||||
oglEnable(GL_STENCIL_TEST, regs.stencil_enable);
|
||||
|
||||
glStencilFuncSeparate(GL_FRONT, MaxwellToGL::ComparisonOp(regs.stencil_front_func_func),
|
||||
regs.stencil_front_func_ref, regs.stencil_front_func_mask);
|
||||
glStencilOpSeparate(GL_FRONT, MaxwellToGL::StencilOp(regs.stencil_front_op_fail),
|
||||
MaxwellToGL::StencilOp(regs.stencil_front_op_zfail),
|
||||
MaxwellToGL::StencilOp(regs.stencil_front_op_zpass));
|
||||
glStencilMaskSeparate(GL_FRONT, regs.stencil_front_mask);
|
||||
glStencilFuncSeparate(GL_FRONT, MaxwellToGL::ComparisonOp(regs.stencil_front_op.func),
|
||||
regs.stencil_front_func.ref, regs.stencil_front_func.func_mask);
|
||||
glStencilOpSeparate(GL_FRONT, MaxwellToGL::StencilOp(regs.stencil_front_op.fail),
|
||||
MaxwellToGL::StencilOp(regs.stencil_front_op.zfail),
|
||||
MaxwellToGL::StencilOp(regs.stencil_front_op.zpass));
|
||||
glStencilMaskSeparate(GL_FRONT, regs.stencil_front_func.mask);
|
||||
|
||||
if (regs.stencil_two_side_enable) {
|
||||
glStencilFuncSeparate(GL_BACK, MaxwellToGL::ComparisonOp(regs.stencil_back_func_func),
|
||||
regs.stencil_back_func_ref, regs.stencil_back_func_mask);
|
||||
glStencilOpSeparate(GL_BACK, MaxwellToGL::StencilOp(regs.stencil_back_op_fail),
|
||||
MaxwellToGL::StencilOp(regs.stencil_back_op_zfail),
|
||||
MaxwellToGL::StencilOp(regs.stencil_back_op_zpass));
|
||||
glStencilMaskSeparate(GL_BACK, regs.stencil_back_mask);
|
||||
glStencilFuncSeparate(GL_BACK, MaxwellToGL::ComparisonOp(regs.stencil_back_op.func),
|
||||
regs.stencil_back_func.ref, regs.stencil_back_func.mask);
|
||||
glStencilOpSeparate(GL_BACK, MaxwellToGL::StencilOp(regs.stencil_back_op.fail),
|
||||
MaxwellToGL::StencilOp(regs.stencil_back_op.zfail),
|
||||
MaxwellToGL::StencilOp(regs.stencil_back_op.zpass));
|
||||
glStencilMaskSeparate(GL_BACK, regs.stencil_back_func.mask);
|
||||
} else {
|
||||
glStencilFuncSeparate(GL_BACK, GL_ALWAYS, 0, 0xFFFFFFFF);
|
||||
glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_KEEP);
|
||||
|
@ -782,7 +784,7 @@ void RasterizerOpenGL::SyncPolygonModes() {
|
|||
flags[Dirty::PolygonModes] = false;
|
||||
|
||||
const auto& regs = maxwell3d->regs;
|
||||
if (regs.fill_rectangle) {
|
||||
if (regs.fill_via_triangle_mode != Maxwell::FillViaTriangleMode::Disabled) {
|
||||
if (!GLAD_GL_NV_fill_rectangle) {
|
||||
LOG_ERROR(Render_OpenGL, "GL_NV_fill_rectangle used and not supported");
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
|
@ -855,8 +857,8 @@ void RasterizerOpenGL::SyncMultiSampleState() {
|
|||
flags[Dirty::MultisampleControl] = false;
|
||||
|
||||
const auto& regs = maxwell3d->regs;
|
||||
oglEnable(GL_SAMPLE_ALPHA_TO_COVERAGE, regs.multisample_control.alpha_to_coverage);
|
||||
oglEnable(GL_SAMPLE_ALPHA_TO_ONE, regs.multisample_control.alpha_to_one);
|
||||
oglEnable(GL_SAMPLE_ALPHA_TO_COVERAGE, regs.anti_alias_alpha_control.alpha_to_coverage);
|
||||
oglEnable(GL_SAMPLE_ALPHA_TO_ONE, regs.anti_alias_alpha_control.alpha_to_one);
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SyncFragmentColorClampState() {
|
||||
|
@ -866,7 +868,8 @@ void RasterizerOpenGL::SyncFragmentColorClampState() {
|
|||
}
|
||||
flags[Dirty::FragmentClampColor] = false;
|
||||
|
||||
glClampColor(GL_CLAMP_FRAGMENT_COLOR, maxwell3d->regs.frag_color_clamp ? GL_TRUE : GL_FALSE);
|
||||
glClampColor(GL_CLAMP_FRAGMENT_COLOR,
|
||||
maxwell3d->regs.frag_color_clamp.AnyEnabled() ? GL_TRUE : GL_FALSE);
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SyncBlendState() {
|
||||
|
@ -886,18 +889,18 @@ void RasterizerOpenGL::SyncBlendState() {
|
|||
}
|
||||
flags[Dirty::BlendStates] = false;
|
||||
|
||||
if (!regs.independent_blend_enable) {
|
||||
if (!regs.blend_per_target_enabled) {
|
||||
if (!regs.blend.enable[0]) {
|
||||
glDisable(GL_BLEND);
|
||||
return;
|
||||
}
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFuncSeparate(MaxwellToGL::BlendFunc(regs.blend.factor_source_rgb),
|
||||
MaxwellToGL::BlendFunc(regs.blend.factor_dest_rgb),
|
||||
MaxwellToGL::BlendFunc(regs.blend.factor_source_a),
|
||||
MaxwellToGL::BlendFunc(regs.blend.factor_dest_a));
|
||||
glBlendEquationSeparate(MaxwellToGL::BlendEquation(regs.blend.equation_rgb),
|
||||
MaxwellToGL::BlendEquation(regs.blend.equation_a));
|
||||
glBlendFuncSeparate(MaxwellToGL::BlendFunc(regs.blend.color_source),
|
||||
MaxwellToGL::BlendFunc(regs.blend.color_dest),
|
||||
MaxwellToGL::BlendFunc(regs.blend.alpha_source),
|
||||
MaxwellToGL::BlendFunc(regs.blend.alpha_dest));
|
||||
glBlendEquationSeparate(MaxwellToGL::BlendEquation(regs.blend.color_op),
|
||||
MaxwellToGL::BlendEquation(regs.blend.alpha_op));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -916,14 +919,13 @@ void RasterizerOpenGL::SyncBlendState() {
|
|||
}
|
||||
glEnablei(GL_BLEND, static_cast<GLuint>(i));
|
||||
|
||||
const auto& src = regs.independent_blend[i];
|
||||
glBlendFuncSeparatei(static_cast<GLuint>(i), MaxwellToGL::BlendFunc(src.factor_source_rgb),
|
||||
MaxwellToGL::BlendFunc(src.factor_dest_rgb),
|
||||
MaxwellToGL::BlendFunc(src.factor_source_a),
|
||||
MaxwellToGL::BlendFunc(src.factor_dest_a));
|
||||
glBlendEquationSeparatei(static_cast<GLuint>(i),
|
||||
MaxwellToGL::BlendEquation(src.equation_rgb),
|
||||
MaxwellToGL::BlendEquation(src.equation_a));
|
||||
const auto& src = regs.blend_per_target[i];
|
||||
glBlendFuncSeparatei(static_cast<GLuint>(i), MaxwellToGL::BlendFunc(src.color_source),
|
||||
MaxwellToGL::BlendFunc(src.color_dest),
|
||||
MaxwellToGL::BlendFunc(src.alpha_source),
|
||||
MaxwellToGL::BlendFunc(src.alpha_dest));
|
||||
glBlendEquationSeparatei(static_cast<GLuint>(i), MaxwellToGL::BlendEquation(src.color_op),
|
||||
MaxwellToGL::BlendEquation(src.alpha_op));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -937,7 +939,7 @@ void RasterizerOpenGL::SyncLogicOpState() {
|
|||
const auto& regs = maxwell3d->regs;
|
||||
if (regs.logic_op.enable) {
|
||||
glEnable(GL_COLOR_LOGIC_OP);
|
||||
glLogicOp(MaxwellToGL::LogicOp(regs.logic_op.operation));
|
||||
glLogicOp(MaxwellToGL::LogicOp(regs.logic_op.op));
|
||||
} else {
|
||||
glDisable(GL_COLOR_LOGIC_OP);
|
||||
}
|
||||
|
@ -996,7 +998,7 @@ void RasterizerOpenGL::SyncPointState() {
|
|||
flags[Dirty::PointSize] = false;
|
||||
|
||||
oglEnable(GL_POINT_SPRITE, maxwell3d->regs.point_sprite_enable);
|
||||
oglEnable(GL_PROGRAM_POINT_SIZE, maxwell3d->regs.vp_point_size.enable);
|
||||
oglEnable(GL_PROGRAM_POINT_SIZE, maxwell3d->regs.point_size_attribute.enabled);
|
||||
const bool is_rescaling{texture_cache.IsRescaling()};
|
||||
const float scale = is_rescaling ? Settings::values.resolution_info.up_factor : 1.0f;
|
||||
glPointSize(std::max(1.0f, maxwell3d->regs.point_size * scale));
|
||||
|
@ -1010,8 +1012,8 @@ void RasterizerOpenGL::SyncLineState() {
|
|||
flags[Dirty::LineWidth] = false;
|
||||
|
||||
const auto& regs = maxwell3d->regs;
|
||||
oglEnable(GL_LINE_SMOOTH, regs.line_smooth_enable);
|
||||
glLineWidth(regs.line_smooth_enable ? regs.line_width_smooth : regs.line_width_aliased);
|
||||
oglEnable(GL_LINE_SMOOTH, regs.line_anti_alias_enable);
|
||||
glLineWidth(regs.line_anti_alias_enable ? regs.line_width_smooth : regs.line_width_aliased);
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SyncPolygonOffset() {
|
||||
|
@ -1029,8 +1031,8 @@ void RasterizerOpenGL::SyncPolygonOffset() {
|
|||
if (regs.polygon_offset_fill_enable || regs.polygon_offset_line_enable ||
|
||||
regs.polygon_offset_point_enable) {
|
||||
// Hardware divides polygon offset units by two
|
||||
glPolygonOffsetClamp(regs.polygon_offset_factor, regs.polygon_offset_units / 2.0f,
|
||||
regs.polygon_offset_clamp);
|
||||
glPolygonOffsetClamp(regs.slope_scale_depth_bias, regs.depth_bias / 2.0f,
|
||||
regs.depth_bias_clamp);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1062,14 +1064,14 @@ void RasterizerOpenGL::SyncFramebufferSRGB() {
|
|||
|
||||
void RasterizerOpenGL::BeginTransformFeedback(GraphicsPipeline* program, GLenum primitive_mode) {
|
||||
const auto& regs = maxwell3d->regs;
|
||||
if (regs.tfb_enabled == 0) {
|
||||
if (regs.transform_feedback_enabled == 0) {
|
||||
return;
|
||||
}
|
||||
program->ConfigureTransformFeedback();
|
||||
|
||||
UNIMPLEMENTED_IF(regs.IsShaderConfigEnabled(Maxwell::ShaderProgram::TesselationControl) ||
|
||||
regs.IsShaderConfigEnabled(Maxwell::ShaderProgram::TesselationEval) ||
|
||||
regs.IsShaderConfigEnabled(Maxwell::ShaderProgram::Geometry));
|
||||
UNIMPLEMENTED_IF(regs.IsShaderConfigEnabled(Maxwell::ShaderType::TessellationInit) ||
|
||||
regs.IsShaderConfigEnabled(Maxwell::ShaderType::Tessellation) ||
|
||||
regs.IsShaderConfigEnabled(Maxwell::ShaderType::Geometry));
|
||||
UNIMPLEMENTED_IF(primitive_mode != GL_POINTS);
|
||||
|
||||
// We may have to call BeginTransformFeedbackNV here since they seem to call different
|
||||
|
@ -1080,7 +1082,7 @@ void RasterizerOpenGL::BeginTransformFeedback(GraphicsPipeline* program, GLenum
|
|||
}
|
||||
|
||||
void RasterizerOpenGL::EndTransformFeedback() {
|
||||
if (maxwell3d->regs.tfb_enabled != 0) {
|
||||
if (maxwell3d->regs.transform_feedback_enabled != 0) {
|
||||
glEndTransformFeedback();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,11 +78,11 @@ Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineKey& key,
|
|||
info.tess_clockwise = key.tessellation_clockwise != 0;
|
||||
info.tess_primitive = [&key] {
|
||||
switch (key.tessellation_primitive) {
|
||||
case Maxwell::TessellationPrimitive::Isolines:
|
||||
case Maxwell::Tessellation::DomainType::Isolines:
|
||||
return Shader::TessPrimitive::Isolines;
|
||||
case Maxwell::TessellationPrimitive::Triangles:
|
||||
case Maxwell::Tessellation::DomainType::Triangles:
|
||||
return Shader::TessPrimitive::Triangles;
|
||||
case Maxwell::TessellationPrimitive::Quads:
|
||||
case Maxwell::Tessellation::DomainType::Quads:
|
||||
return Shader::TessPrimitive::Quads;
|
||||
}
|
||||
ASSERT(false);
|
||||
|
@ -90,11 +90,11 @@ Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineKey& key,
|
|||
}();
|
||||
info.tess_spacing = [&] {
|
||||
switch (key.tessellation_spacing) {
|
||||
case Maxwell::TessellationSpacing::Equal:
|
||||
case Maxwell::Tessellation::Spacing::Integer:
|
||||
return Shader::TessSpacing::Equal;
|
||||
case Maxwell::TessellationSpacing::FractionalOdd:
|
||||
case Maxwell::Tessellation::Spacing::FractionalOdd:
|
||||
return Shader::TessSpacing::FractionalOdd;
|
||||
case Maxwell::TessellationSpacing::FractionalEven:
|
||||
case Maxwell::Tessellation::Spacing::FractionalEven:
|
||||
return Shader::TessSpacing::FractionalEven;
|
||||
}
|
||||
ASSERT(false);
|
||||
|
@ -139,14 +139,15 @@ Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineKey& key,
|
|||
}
|
||||
|
||||
void SetXfbState(VideoCommon::TransformFeedbackState& state, const Maxwell& regs) {
|
||||
std::ranges::transform(regs.tfb_layouts, state.layouts.begin(), [](const auto& layout) {
|
||||
return VideoCommon::TransformFeedbackState::Layout{
|
||||
.stream = layout.stream,
|
||||
.varying_count = layout.varying_count,
|
||||
.stride = layout.stride,
|
||||
};
|
||||
});
|
||||
state.varyings = regs.tfb_varying_locs;
|
||||
std::ranges::transform(regs.transform_feedback.controls, state.layouts.begin(),
|
||||
[](const auto& layout) {
|
||||
return VideoCommon::TransformFeedbackState::Layout{
|
||||
.stream = layout.stream,
|
||||
.varying_count = layout.varying_count,
|
||||
.stride = layout.stride,
|
||||
};
|
||||
});
|
||||
state.varyings = regs.stream_out_layout;
|
||||
}
|
||||
} // Anonymous namespace
|
||||
|
||||
|
@ -309,14 +310,16 @@ GraphicsPipeline* ShaderCache::CurrentGraphicsPipeline() {
|
|||
}
|
||||
const auto& regs{maxwell3d->regs};
|
||||
graphics_key.raw = 0;
|
||||
graphics_key.early_z.Assign(regs.force_early_fragment_tests != 0 ? 1 : 0);
|
||||
graphics_key.early_z.Assign(regs.mandated_early_z != 0 ? 1 : 0);
|
||||
graphics_key.gs_input_topology.Assign(graphics_key.unique_hashes[4] != 0
|
||||
? regs.draw.topology.Value()
|
||||
: Maxwell::PrimitiveTopology{});
|
||||
graphics_key.tessellation_primitive.Assign(regs.tess_mode.prim.Value());
|
||||
graphics_key.tessellation_spacing.Assign(regs.tess_mode.spacing.Value());
|
||||
graphics_key.tessellation_clockwise.Assign(regs.tess_mode.cw.Value());
|
||||
graphics_key.xfb_enabled.Assign(regs.tfb_enabled != 0 ? 1 : 0);
|
||||
graphics_key.tessellation_primitive.Assign(regs.tessellation.params.domain_type.Value());
|
||||
graphics_key.tessellation_spacing.Assign(regs.tessellation.params.spacing.Value());
|
||||
graphics_key.tessellation_clockwise.Assign(
|
||||
regs.tessellation.params.output_primitives.Value() !=
|
||||
Maxwell::Tessellation::OutputPrimitves::Triangles_CCW);
|
||||
graphics_key.xfb_enabled.Assign(regs.transform_feedback_enabled != 0 ? 1 : 0);
|
||||
if (graphics_key.xfb_enabled) {
|
||||
SetXfbState(graphics_key.xfb_state, regs);
|
||||
}
|
||||
|
@ -354,7 +357,7 @@ GraphicsPipeline* ShaderCache::BuiltPipeline(GraphicsPipeline* pipeline) const n
|
|||
// If games are using a small index count, we can assume these are full screen quads.
|
||||
// Usually these shaders are only used once for building textures so we can assume they
|
||||
// can't be built async
|
||||
if (maxwell3d->regs.index_array.count <= 6 || maxwell3d->regs.vertex_buffer.count <= 6) {
|
||||
if (maxwell3d->regs.index_buffer.count <= 6 || maxwell3d->regs.vertex_buffer.count <= 6) {
|
||||
return pipeline;
|
||||
}
|
||||
return nullptr;
|
||||
|
|
|
@ -38,12 +38,12 @@ void SetupDirtyColorMasks(Tables& tables) {
|
|||
void SetupDirtyVertexInstances(Tables& tables) {
|
||||
static constexpr std::size_t instance_base_offset = 3;
|
||||
for (std::size_t i = 0; i < Regs::NumVertexArrays; ++i) {
|
||||
const std::size_t array_offset = OFF(vertex_array) + i * NUM(vertex_array[0]);
|
||||
const std::size_t array_offset = OFF(vertex_streams) + i * NUM(vertex_streams[0]);
|
||||
const std::size_t instance_array_offset = array_offset + instance_base_offset;
|
||||
tables[0][instance_array_offset] = static_cast<u8>(VertexInstance0 + i);
|
||||
tables[1][instance_array_offset] = VertexInstances;
|
||||
|
||||
const std::size_t instance_offset = OFF(instanced_arrays) + i;
|
||||
const std::size_t instance_offset = OFF(vertex_stream_instances) + i;
|
||||
tables[0][instance_offset] = static_cast<u8>(VertexInstance0 + i);
|
||||
tables[1][instance_offset] = VertexInstances;
|
||||
}
|
||||
|
@ -70,8 +70,8 @@ void SetupDirtyViewports(Tables& tables) {
|
|||
FillBlock(tables[1], OFF(viewport_transform), NUM(viewport_transform), Viewports);
|
||||
FillBlock(tables[1], OFF(viewports), NUM(viewports), Viewports);
|
||||
|
||||
tables[0][OFF(viewport_transform_enabled)] = ViewportTransform;
|
||||
tables[1][OFF(viewport_transform_enabled)] = Viewports;
|
||||
tables[0][OFF(viewport_scale_offset_enbled)] = ViewportTransform;
|
||||
tables[1][OFF(viewport_scale_offset_enbled)] = Viewports;
|
||||
}
|
||||
|
||||
void SetupDirtyScissors(Tables& tables) {
|
||||
|
@ -88,7 +88,7 @@ void SetupDirtyPolygonModes(Tables& tables) {
|
|||
|
||||
tables[1][OFF(polygon_mode_front)] = PolygonModes;
|
||||
tables[1][OFF(polygon_mode_back)] = PolygonModes;
|
||||
tables[0][OFF(fill_rectangle)] = PolygonModes;
|
||||
tables[0][OFF(fill_via_triangle_mode)] = PolygonModes;
|
||||
}
|
||||
|
||||
void SetupDirtyDepthTest(Tables& tables) {
|
||||
|
@ -100,12 +100,14 @@ void SetupDirtyDepthTest(Tables& tables) {
|
|||
|
||||
void SetupDirtyStencilTest(Tables& tables) {
|
||||
static constexpr std::array offsets = {
|
||||
OFF(stencil_enable), OFF(stencil_front_func_func), OFF(stencil_front_func_ref),
|
||||
OFF(stencil_front_func_mask), OFF(stencil_front_op_fail), OFF(stencil_front_op_zfail),
|
||||
OFF(stencil_front_op_zpass), OFF(stencil_front_mask), OFF(stencil_two_side_enable),
|
||||
OFF(stencil_back_func_func), OFF(stencil_back_func_ref), OFF(stencil_back_func_mask),
|
||||
OFF(stencil_back_op_fail), OFF(stencil_back_op_zfail), OFF(stencil_back_op_zpass),
|
||||
OFF(stencil_back_mask)};
|
||||
OFF(stencil_enable), OFF(stencil_front_op.func),
|
||||
OFF(stencil_front_func.ref), OFF(stencil_front_func.func_mask),
|
||||
OFF(stencil_front_op.fail), OFF(stencil_front_op.zfail),
|
||||
OFF(stencil_front_op.zpass), OFF(stencil_front_func.mask),
|
||||
OFF(stencil_two_side_enable), OFF(stencil_back_op.func),
|
||||
OFF(stencil_back_func.ref), OFF(stencil_back_func.func_mask),
|
||||
OFF(stencil_back_op.fail), OFF(stencil_back_op.zfail),
|
||||
OFF(stencil_back_op.zpass), OFF(stencil_back_func.mask)};
|
||||
for (const auto offset : offsets) {
|
||||
tables[0][offset] = StencilTest;
|
||||
}
|
||||
|
@ -121,15 +123,15 @@ void SetupDirtyAlphaTest(Tables& tables) {
|
|||
void SetupDirtyBlend(Tables& tables) {
|
||||
FillBlock(tables[0], OFF(blend_color), NUM(blend_color), BlendColor);
|
||||
|
||||
tables[0][OFF(independent_blend_enable)] = BlendIndependentEnabled;
|
||||
tables[0][OFF(blend_per_target_enabled)] = BlendIndependentEnabled;
|
||||
|
||||
for (std::size_t i = 0; i < Regs::NumRenderTargets; ++i) {
|
||||
const std::size_t offset = OFF(independent_blend) + i * NUM(independent_blend[0]);
|
||||
FillBlock(tables[0], offset, NUM(independent_blend[0]), BlendState0 + i);
|
||||
const std::size_t offset = OFF(blend_per_target) + i * NUM(blend_per_target[0]);
|
||||
FillBlock(tables[0], offset, NUM(blend_per_target[0]), BlendState0 + i);
|
||||
|
||||
tables[0][OFF(blend.enable) + i] = static_cast<u8>(BlendState0 + i);
|
||||
}
|
||||
FillBlock(tables[1], OFF(independent_blend), NUM(independent_blend), BlendStates);
|
||||
FillBlock(tables[1], OFF(blend_per_target), NUM(blend_per_target), BlendStates);
|
||||
FillBlock(tables[1], OFF(blend), NUM(blend), BlendStates);
|
||||
}
|
||||
|
||||
|
@ -142,13 +144,14 @@ void SetupDirtyPolygonOffset(Tables& tables) {
|
|||
table[OFF(polygon_offset_fill_enable)] = PolygonOffset;
|
||||
table[OFF(polygon_offset_line_enable)] = PolygonOffset;
|
||||
table[OFF(polygon_offset_point_enable)] = PolygonOffset;
|
||||
table[OFF(polygon_offset_factor)] = PolygonOffset;
|
||||
table[OFF(polygon_offset_units)] = PolygonOffset;
|
||||
table[OFF(polygon_offset_clamp)] = PolygonOffset;
|
||||
table[OFF(slope_scale_depth_bias)] = PolygonOffset;
|
||||
table[OFF(depth_bias)] = PolygonOffset;
|
||||
table[OFF(depth_bias_clamp)] = PolygonOffset;
|
||||
}
|
||||
|
||||
void SetupDirtyMultisampleControl(Tables& tables) {
|
||||
FillBlock(tables[0], OFF(multisample_control), NUM(multisample_control), MultisampleControl);
|
||||
FillBlock(tables[0], OFF(anti_alias_alpha_control), NUM(anti_alias_alpha_control),
|
||||
MultisampleControl);
|
||||
}
|
||||
|
||||
void SetupDirtyRasterizeEnable(Tables& tables) {
|
||||
|
@ -168,7 +171,7 @@ void SetupDirtyFragmentClampColor(Tables& tables) {
|
|||
}
|
||||
|
||||
void SetupDirtyPointSize(Tables& tables) {
|
||||
tables[0][OFF(vp_point_size)] = PointSize;
|
||||
tables[0][OFF(point_size_attribute)] = PointSize;
|
||||
tables[0][OFF(point_size)] = PointSize;
|
||||
tables[0][OFF(point_sprite_enable)] = PointSize;
|
||||
}
|
||||
|
@ -176,28 +179,28 @@ void SetupDirtyPointSize(Tables& tables) {
|
|||
void SetupDirtyLineWidth(Tables& tables) {
|
||||
tables[0][OFF(line_width_smooth)] = LineWidth;
|
||||
tables[0][OFF(line_width_aliased)] = LineWidth;
|
||||
tables[0][OFF(line_smooth_enable)] = LineWidth;
|
||||
tables[0][OFF(line_anti_alias_enable)] = LineWidth;
|
||||
}
|
||||
|
||||
void SetupDirtyClipControl(Tables& tables) {
|
||||
auto& table = tables[0];
|
||||
table[OFF(screen_y_control)] = ClipControl;
|
||||
table[OFF(window_origin)] = ClipControl;
|
||||
table[OFF(depth_mode)] = ClipControl;
|
||||
}
|
||||
|
||||
void SetupDirtyDepthClampEnabled(Tables& tables) {
|
||||
tables[0][OFF(view_volume_clip_control)] = DepthClampEnabled;
|
||||
tables[0][OFF(viewport_clip_control)] = DepthClampEnabled;
|
||||
}
|
||||
|
||||
void SetupDirtyMisc(Tables& tables) {
|
||||
auto& table = tables[0];
|
||||
|
||||
table[OFF(clip_distance_enabled)] = ClipDistances;
|
||||
table[OFF(user_clip_enable)] = ClipDistances;
|
||||
|
||||
table[OFF(front_face)] = FrontFace;
|
||||
table[OFF(gl_front_face)] = FrontFace;
|
||||
|
||||
table[OFF(cull_test_enabled)] = CullTest;
|
||||
table[OFF(cull_face)] = CullTest;
|
||||
table[OFF(gl_cull_test_enabled)] = CullTest;
|
||||
table[OFF(gl_cull_face)] = CullTest;
|
||||
}
|
||||
|
||||
} // Anonymous namespace
|
||||
|
|
|
@ -126,51 +126,60 @@ inline const FormatTuple& GetFormatTuple(VideoCore::Surface::PixelFormat pixel_f
|
|||
|
||||
inline GLenum VertexFormat(Maxwell::VertexAttribute attrib) {
|
||||
switch (attrib.type) {
|
||||
case Maxwell::VertexAttribute::Type::UnsignedNorm:
|
||||
case Maxwell::VertexAttribute::Type::UnsignedScaled:
|
||||
case Maxwell::VertexAttribute::Type::UnsignedInt:
|
||||
case Maxwell::VertexAttribute::Type::UnusedEnumDoNotUseBecauseItWillGoAway:
|
||||
ASSERT_MSG(false, "Invalid vertex attribute type!");
|
||||
break;
|
||||
case Maxwell::VertexAttribute::Type::UNorm:
|
||||
case Maxwell::VertexAttribute::Type::UScaled:
|
||||
case Maxwell::VertexAttribute::Type::UInt:
|
||||
switch (attrib.size) {
|
||||
case Maxwell::VertexAttribute::Size::Size_8:
|
||||
case Maxwell::VertexAttribute::Size::Size_8_8:
|
||||
case Maxwell::VertexAttribute::Size::Size_8_8_8:
|
||||
case Maxwell::VertexAttribute::Size::Size_8_8_8_8:
|
||||
case Maxwell::VertexAttribute::Size::Size_R8:
|
||||
case Maxwell::VertexAttribute::Size::Size_A8:
|
||||
case Maxwell::VertexAttribute::Size::Size_R8_G8:
|
||||
case Maxwell::VertexAttribute::Size::Size_G8_R8:
|
||||
case Maxwell::VertexAttribute::Size::Size_R8_G8_B8:
|
||||
case Maxwell::VertexAttribute::Size::Size_R8_G8_B8_A8:
|
||||
case Maxwell::VertexAttribute::Size::Size_X8_B8_G8_R8:
|
||||
return GL_UNSIGNED_BYTE;
|
||||
case Maxwell::VertexAttribute::Size::Size_16:
|
||||
case Maxwell::VertexAttribute::Size::Size_16_16:
|
||||
case Maxwell::VertexAttribute::Size::Size_16_16_16:
|
||||
case Maxwell::VertexAttribute::Size::Size_16_16_16_16:
|
||||
case Maxwell::VertexAttribute::Size::Size_R16:
|
||||
case Maxwell::VertexAttribute::Size::Size_R16_G16:
|
||||
case Maxwell::VertexAttribute::Size::Size_R16_G16_B16:
|
||||
case Maxwell::VertexAttribute::Size::Size_R16_G16_B16_A16:
|
||||
return GL_UNSIGNED_SHORT;
|
||||
case Maxwell::VertexAttribute::Size::Size_32:
|
||||
case Maxwell::VertexAttribute::Size::Size_32_32:
|
||||
case Maxwell::VertexAttribute::Size::Size_32_32_32:
|
||||
case Maxwell::VertexAttribute::Size::Size_32_32_32_32:
|
||||
case Maxwell::VertexAttribute::Size::Size_R32:
|
||||
case Maxwell::VertexAttribute::Size::Size_R32_G32:
|
||||
case Maxwell::VertexAttribute::Size::Size_R32_G32_B32:
|
||||
case Maxwell::VertexAttribute::Size::Size_R32_G32_B32_A32:
|
||||
return GL_UNSIGNED_INT;
|
||||
case Maxwell::VertexAttribute::Size::Size_10_10_10_2:
|
||||
case Maxwell::VertexAttribute::Size::Size_A2_B10_G10_R10:
|
||||
return GL_UNSIGNED_INT_2_10_10_10_REV;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case Maxwell::VertexAttribute::Type::SignedNorm:
|
||||
case Maxwell::VertexAttribute::Type::SignedScaled:
|
||||
case Maxwell::VertexAttribute::Type::SignedInt:
|
||||
case Maxwell::VertexAttribute::Type::SNorm:
|
||||
case Maxwell::VertexAttribute::Type::SScaled:
|
||||
case Maxwell::VertexAttribute::Type::SInt:
|
||||
switch (attrib.size) {
|
||||
case Maxwell::VertexAttribute::Size::Size_8:
|
||||
case Maxwell::VertexAttribute::Size::Size_8_8:
|
||||
case Maxwell::VertexAttribute::Size::Size_8_8_8:
|
||||
case Maxwell::VertexAttribute::Size::Size_8_8_8_8:
|
||||
case Maxwell::VertexAttribute::Size::Size_R8:
|
||||
case Maxwell::VertexAttribute::Size::Size_A8:
|
||||
case Maxwell::VertexAttribute::Size::Size_R8_G8:
|
||||
case Maxwell::VertexAttribute::Size::Size_G8_R8:
|
||||
case Maxwell::VertexAttribute::Size::Size_R8_G8_B8:
|
||||
case Maxwell::VertexAttribute::Size::Size_R8_G8_B8_A8:
|
||||
case Maxwell::VertexAttribute::Size::Size_X8_B8_G8_R8:
|
||||
return GL_BYTE;
|
||||
case Maxwell::VertexAttribute::Size::Size_16:
|
||||
case Maxwell::VertexAttribute::Size::Size_16_16:
|
||||
case Maxwell::VertexAttribute::Size::Size_16_16_16:
|
||||
case Maxwell::VertexAttribute::Size::Size_16_16_16_16:
|
||||
case Maxwell::VertexAttribute::Size::Size_R16:
|
||||
case Maxwell::VertexAttribute::Size::Size_R16_G16:
|
||||
case Maxwell::VertexAttribute::Size::Size_R16_G16_B16:
|
||||
case Maxwell::VertexAttribute::Size::Size_R16_G16_B16_A16:
|
||||
return GL_SHORT;
|
||||
case Maxwell::VertexAttribute::Size::Size_32:
|
||||
case Maxwell::VertexAttribute::Size::Size_32_32:
|
||||
case Maxwell::VertexAttribute::Size::Size_32_32_32:
|
||||
case Maxwell::VertexAttribute::Size::Size_32_32_32_32:
|
||||
case Maxwell::VertexAttribute::Size::Size_R32:
|
||||
case Maxwell::VertexAttribute::Size::Size_R32_G32:
|
||||
case Maxwell::VertexAttribute::Size::Size_R32_G32_B32:
|
||||
case Maxwell::VertexAttribute::Size::Size_R32_G32_B32_A32:
|
||||
return GL_INT;
|
||||
case Maxwell::VertexAttribute::Size::Size_10_10_10_2:
|
||||
case Maxwell::VertexAttribute::Size::Size_A2_B10_G10_R10:
|
||||
return GL_INT_2_10_10_10_REV;
|
||||
default:
|
||||
break;
|
||||
|
@ -178,17 +187,17 @@ inline GLenum VertexFormat(Maxwell::VertexAttribute attrib) {
|
|||
break;
|
||||
case Maxwell::VertexAttribute::Type::Float:
|
||||
switch (attrib.size) {
|
||||
case Maxwell::VertexAttribute::Size::Size_16:
|
||||
case Maxwell::VertexAttribute::Size::Size_16_16:
|
||||
case Maxwell::VertexAttribute::Size::Size_16_16_16:
|
||||
case Maxwell::VertexAttribute::Size::Size_16_16_16_16:
|
||||
case Maxwell::VertexAttribute::Size::Size_R16:
|
||||
case Maxwell::VertexAttribute::Size::Size_R16_G16:
|
||||
case Maxwell::VertexAttribute::Size::Size_R16_G16_B16:
|
||||
case Maxwell::VertexAttribute::Size::Size_R16_G16_B16_A16:
|
||||
return GL_HALF_FLOAT;
|
||||
case Maxwell::VertexAttribute::Size::Size_32:
|
||||
case Maxwell::VertexAttribute::Size::Size_32_32:
|
||||
case Maxwell::VertexAttribute::Size::Size_32_32_32:
|
||||
case Maxwell::VertexAttribute::Size::Size_32_32_32_32:
|
||||
case Maxwell::VertexAttribute::Size::Size_R32:
|
||||
case Maxwell::VertexAttribute::Size::Size_R32_G32:
|
||||
case Maxwell::VertexAttribute::Size::Size_R32_G32_B32:
|
||||
case Maxwell::VertexAttribute::Size::Size_R32_G32_B32_A32:
|
||||
return GL_FLOAT;
|
||||
case Maxwell::VertexAttribute::Size::Size_11_11_10:
|
||||
case Maxwell::VertexAttribute::Size::Size_B10_G11_R11:
|
||||
return GL_UNSIGNED_INT_10F_11F_11F_REV;
|
||||
default:
|
||||
break;
|
||||
|
@ -335,20 +344,20 @@ inline GLenum DepthCompareFunc(Tegra::Texture::DepthCompareFunc func) {
|
|||
|
||||
inline GLenum BlendEquation(Maxwell::Blend::Equation equation) {
|
||||
switch (equation) {
|
||||
case Maxwell::Blend::Equation::Add:
|
||||
case Maxwell::Blend::Equation::AddGL:
|
||||
case Maxwell::Blend::Equation::Add_D3D:
|
||||
case Maxwell::Blend::Equation::Add_GL:
|
||||
return GL_FUNC_ADD;
|
||||
case Maxwell::Blend::Equation::Subtract:
|
||||
case Maxwell::Blend::Equation::SubtractGL:
|
||||
case Maxwell::Blend::Equation::Subtract_D3D:
|
||||
case Maxwell::Blend::Equation::Subtract_GL:
|
||||
return GL_FUNC_SUBTRACT;
|
||||
case Maxwell::Blend::Equation::ReverseSubtract:
|
||||
case Maxwell::Blend::Equation::ReverseSubtractGL:
|
||||
case Maxwell::Blend::Equation::ReverseSubtract_D3D:
|
||||
case Maxwell::Blend::Equation::ReverseSubtract_GL:
|
||||
return GL_FUNC_REVERSE_SUBTRACT;
|
||||
case Maxwell::Blend::Equation::Min:
|
||||
case Maxwell::Blend::Equation::MinGL:
|
||||
case Maxwell::Blend::Equation::Min_D3D:
|
||||
case Maxwell::Blend::Equation::Min_GL:
|
||||
return GL_MIN;
|
||||
case Maxwell::Blend::Equation::Max:
|
||||
case Maxwell::Blend::Equation::MaxGL:
|
||||
case Maxwell::Blend::Equation::Max_D3D:
|
||||
case Maxwell::Blend::Equation::Max_GL:
|
||||
return GL_MAX;
|
||||
}
|
||||
UNIMPLEMENTED_MSG("Unimplemented blend equation={}", equation);
|
||||
|
@ -357,62 +366,62 @@ inline GLenum BlendEquation(Maxwell::Blend::Equation equation) {
|
|||
|
||||
inline GLenum BlendFunc(Maxwell::Blend::Factor factor) {
|
||||
switch (factor) {
|
||||
case Maxwell::Blend::Factor::Zero:
|
||||
case Maxwell::Blend::Factor::ZeroGL:
|
||||
case Maxwell::Blend::Factor::Zero_D3D:
|
||||
case Maxwell::Blend::Factor::Zero_GL:
|
||||
return GL_ZERO;
|
||||
case Maxwell::Blend::Factor::One:
|
||||
case Maxwell::Blend::Factor::OneGL:
|
||||
case Maxwell::Blend::Factor::One_D3D:
|
||||
case Maxwell::Blend::Factor::One_GL:
|
||||
return GL_ONE;
|
||||
case Maxwell::Blend::Factor::SourceColor:
|
||||
case Maxwell::Blend::Factor::SourceColorGL:
|
||||
case Maxwell::Blend::Factor::SourceColor_D3D:
|
||||
case Maxwell::Blend::Factor::SourceColor_GL:
|
||||
return GL_SRC_COLOR;
|
||||
case Maxwell::Blend::Factor::OneMinusSourceColor:
|
||||
case Maxwell::Blend::Factor::OneMinusSourceColorGL:
|
||||
case Maxwell::Blend::Factor::OneMinusSourceColor_D3D:
|
||||
case Maxwell::Blend::Factor::OneMinusSourceColor_GL:
|
||||
return GL_ONE_MINUS_SRC_COLOR;
|
||||
case Maxwell::Blend::Factor::SourceAlpha:
|
||||
case Maxwell::Blend::Factor::SourceAlphaGL:
|
||||
case Maxwell::Blend::Factor::SourceAlpha_D3D:
|
||||
case Maxwell::Blend::Factor::SourceAlpha_GL:
|
||||
return GL_SRC_ALPHA;
|
||||
case Maxwell::Blend::Factor::OneMinusSourceAlpha:
|
||||
case Maxwell::Blend::Factor::OneMinusSourceAlphaGL:
|
||||
case Maxwell::Blend::Factor::OneMinusSourceAlpha_D3D:
|
||||
case Maxwell::Blend::Factor::OneMinusSourceAlpha_GL:
|
||||
return GL_ONE_MINUS_SRC_ALPHA;
|
||||
case Maxwell::Blend::Factor::DestAlpha:
|
||||
case Maxwell::Blend::Factor::DestAlphaGL:
|
||||
case Maxwell::Blend::Factor::DestAlpha_D3D:
|
||||
case Maxwell::Blend::Factor::DestAlpha_GL:
|
||||
return GL_DST_ALPHA;
|
||||
case Maxwell::Blend::Factor::OneMinusDestAlpha:
|
||||
case Maxwell::Blend::Factor::OneMinusDestAlphaGL:
|
||||
case Maxwell::Blend::Factor::OneMinusDestAlpha_D3D:
|
||||
case Maxwell::Blend::Factor::OneMinusDestAlpha_GL:
|
||||
return GL_ONE_MINUS_DST_ALPHA;
|
||||
case Maxwell::Blend::Factor::DestColor:
|
||||
case Maxwell::Blend::Factor::DestColorGL:
|
||||
case Maxwell::Blend::Factor::DestColor_D3D:
|
||||
case Maxwell::Blend::Factor::DestColor_GL:
|
||||
return GL_DST_COLOR;
|
||||
case Maxwell::Blend::Factor::OneMinusDestColor:
|
||||
case Maxwell::Blend::Factor::OneMinusDestColorGL:
|
||||
case Maxwell::Blend::Factor::OneMinusDestColor_D3D:
|
||||
case Maxwell::Blend::Factor::OneMinusDestColor_GL:
|
||||
return GL_ONE_MINUS_DST_COLOR;
|
||||
case Maxwell::Blend::Factor::SourceAlphaSaturate:
|
||||
case Maxwell::Blend::Factor::SourceAlphaSaturateGL:
|
||||
case Maxwell::Blend::Factor::SourceAlphaSaturate_D3D:
|
||||
case Maxwell::Blend::Factor::SourceAlphaSaturate_GL:
|
||||
return GL_SRC_ALPHA_SATURATE;
|
||||
case Maxwell::Blend::Factor::Source1Color:
|
||||
case Maxwell::Blend::Factor::Source1ColorGL:
|
||||
case Maxwell::Blend::Factor::Source1Color_D3D:
|
||||
case Maxwell::Blend::Factor::Source1Color_GL:
|
||||
return GL_SRC1_COLOR;
|
||||
case Maxwell::Blend::Factor::OneMinusSource1Color:
|
||||
case Maxwell::Blend::Factor::OneMinusSource1ColorGL:
|
||||
case Maxwell::Blend::Factor::OneMinusSource1Color_D3D:
|
||||
case Maxwell::Blend::Factor::OneMinusSource1Color_GL:
|
||||
return GL_ONE_MINUS_SRC1_COLOR;
|
||||
case Maxwell::Blend::Factor::Source1Alpha:
|
||||
case Maxwell::Blend::Factor::Source1AlphaGL:
|
||||
case Maxwell::Blend::Factor::Source1Alpha_D3D:
|
||||
case Maxwell::Blend::Factor::Source1Alpha_GL:
|
||||
return GL_SRC1_ALPHA;
|
||||
case Maxwell::Blend::Factor::OneMinusSource1Alpha:
|
||||
case Maxwell::Blend::Factor::OneMinusSource1AlphaGL:
|
||||
case Maxwell::Blend::Factor::OneMinusSource1Alpha_D3D:
|
||||
case Maxwell::Blend::Factor::OneMinusSource1Alpha_GL:
|
||||
return GL_ONE_MINUS_SRC1_ALPHA;
|
||||
case Maxwell::Blend::Factor::ConstantColor:
|
||||
case Maxwell::Blend::Factor::ConstantColorGL:
|
||||
case Maxwell::Blend::Factor::BlendFactor_D3D:
|
||||
case Maxwell::Blend::Factor::ConstantColor_GL:
|
||||
return GL_CONSTANT_COLOR;
|
||||
case Maxwell::Blend::Factor::OneMinusConstantColor:
|
||||
case Maxwell::Blend::Factor::OneMinusConstantColorGL:
|
||||
case Maxwell::Blend::Factor::OneMinusBlendFactor_D3D:
|
||||
case Maxwell::Blend::Factor::OneMinusConstantColor_GL:
|
||||
return GL_ONE_MINUS_CONSTANT_COLOR;
|
||||
case Maxwell::Blend::Factor::ConstantAlpha:
|
||||
case Maxwell::Blend::Factor::ConstantAlphaGL:
|
||||
case Maxwell::Blend::Factor::BothSourceAlpha_D3D:
|
||||
case Maxwell::Blend::Factor::ConstantAlpha_GL:
|
||||
return GL_CONSTANT_ALPHA;
|
||||
case Maxwell::Blend::Factor::OneMinusConstantAlpha:
|
||||
case Maxwell::Blend::Factor::OneMinusConstantAlphaGL:
|
||||
case Maxwell::Blend::Factor::OneMinusBothSourceAlpha_D3D:
|
||||
case Maxwell::Blend::Factor::OneMinusConstantAlpha_GL:
|
||||
return GL_ONE_MINUS_CONSTANT_ALPHA;
|
||||
}
|
||||
UNIMPLEMENTED_MSG("Unimplemented blend factor={}", factor);
|
||||
|
@ -421,60 +430,60 @@ inline GLenum BlendFunc(Maxwell::Blend::Factor factor) {
|
|||
|
||||
inline GLenum ComparisonOp(Maxwell::ComparisonOp comparison) {
|
||||
switch (comparison) {
|
||||
case Maxwell::ComparisonOp::Never:
|
||||
case Maxwell::ComparisonOp::NeverOld:
|
||||
case Maxwell::ComparisonOp::Never_D3D:
|
||||
case Maxwell::ComparisonOp::Never_GL:
|
||||
return GL_NEVER;
|
||||
case Maxwell::ComparisonOp::Less:
|
||||
case Maxwell::ComparisonOp::LessOld:
|
||||
case Maxwell::ComparisonOp::Less_D3D:
|
||||
case Maxwell::ComparisonOp::Less_GL:
|
||||
return GL_LESS;
|
||||
case Maxwell::ComparisonOp::Equal:
|
||||
case Maxwell::ComparisonOp::EqualOld:
|
||||
case Maxwell::ComparisonOp::Equal_D3D:
|
||||
case Maxwell::ComparisonOp::Equal_GL:
|
||||
return GL_EQUAL;
|
||||
case Maxwell::ComparisonOp::LessEqual:
|
||||
case Maxwell::ComparisonOp::LessEqualOld:
|
||||
case Maxwell::ComparisonOp::LessEqual_D3D:
|
||||
case Maxwell::ComparisonOp::LessEqual_GL:
|
||||
return GL_LEQUAL;
|
||||
case Maxwell::ComparisonOp::Greater:
|
||||
case Maxwell::ComparisonOp::GreaterOld:
|
||||
case Maxwell::ComparisonOp::Greater_D3D:
|
||||
case Maxwell::ComparisonOp::Greater_GL:
|
||||
return GL_GREATER;
|
||||
case Maxwell::ComparisonOp::NotEqual:
|
||||
case Maxwell::ComparisonOp::NotEqualOld:
|
||||
case Maxwell::ComparisonOp::NotEqual_D3D:
|
||||
case Maxwell::ComparisonOp::NotEqual_GL:
|
||||
return GL_NOTEQUAL;
|
||||
case Maxwell::ComparisonOp::GreaterEqual:
|
||||
case Maxwell::ComparisonOp::GreaterEqualOld:
|
||||
case Maxwell::ComparisonOp::GreaterEqual_D3D:
|
||||
case Maxwell::ComparisonOp::GreaterEqual_GL:
|
||||
return GL_GEQUAL;
|
||||
case Maxwell::ComparisonOp::Always:
|
||||
case Maxwell::ComparisonOp::AlwaysOld:
|
||||
case Maxwell::ComparisonOp::Always_D3D:
|
||||
case Maxwell::ComparisonOp::Always_GL:
|
||||
return GL_ALWAYS;
|
||||
}
|
||||
UNIMPLEMENTED_MSG("Unimplemented comparison op={}", comparison);
|
||||
return GL_ALWAYS;
|
||||
}
|
||||
|
||||
inline GLenum StencilOp(Maxwell::StencilOp stencil) {
|
||||
inline GLenum StencilOp(Maxwell::StencilOp::Op stencil) {
|
||||
switch (stencil) {
|
||||
case Maxwell::StencilOp::Keep:
|
||||
case Maxwell::StencilOp::KeepOGL:
|
||||
case Maxwell::StencilOp::Op::Keep_D3D:
|
||||
case Maxwell::StencilOp::Op::Keep_GL:
|
||||
return GL_KEEP;
|
||||
case Maxwell::StencilOp::Zero:
|
||||
case Maxwell::StencilOp::ZeroOGL:
|
||||
case Maxwell::StencilOp::Op::Zero_D3D:
|
||||
case Maxwell::StencilOp::Op::Zero_GL:
|
||||
return GL_ZERO;
|
||||
case Maxwell::StencilOp::Replace:
|
||||
case Maxwell::StencilOp::ReplaceOGL:
|
||||
case Maxwell::StencilOp::Op::Replace_D3D:
|
||||
case Maxwell::StencilOp::Op::Replace_GL:
|
||||
return GL_REPLACE;
|
||||
case Maxwell::StencilOp::Incr:
|
||||
case Maxwell::StencilOp::IncrOGL:
|
||||
case Maxwell::StencilOp::Op::IncrSaturate_D3D:
|
||||
case Maxwell::StencilOp::Op::IncrSaturate_GL:
|
||||
return GL_INCR;
|
||||
case Maxwell::StencilOp::Decr:
|
||||
case Maxwell::StencilOp::DecrOGL:
|
||||
case Maxwell::StencilOp::Op::DecrSaturate_D3D:
|
||||
case Maxwell::StencilOp::Op::DecrSaturate_GL:
|
||||
return GL_DECR;
|
||||
case Maxwell::StencilOp::Invert:
|
||||
case Maxwell::StencilOp::InvertOGL:
|
||||
case Maxwell::StencilOp::Op::Invert_D3D:
|
||||
case Maxwell::StencilOp::Op::Invert_GL:
|
||||
return GL_INVERT;
|
||||
case Maxwell::StencilOp::IncrWrap:
|
||||
case Maxwell::StencilOp::IncrWrapOGL:
|
||||
case Maxwell::StencilOp::Op::Incr_D3D:
|
||||
case Maxwell::StencilOp::Op::Incr_GL:
|
||||
return GL_INCR_WRAP;
|
||||
case Maxwell::StencilOp::DecrWrap:
|
||||
case Maxwell::StencilOp::DecrWrapOGL:
|
||||
case Maxwell::StencilOp::Op::Decr_D3D:
|
||||
case Maxwell::StencilOp::Op::Decr_GL:
|
||||
return GL_DECR_WRAP;
|
||||
}
|
||||
UNIMPLEMENTED_MSG("Unimplemented stencil op={}", stencil);
|
||||
|
@ -505,39 +514,39 @@ inline GLenum CullFace(Maxwell::CullFace cull_face) {
|
|||
return GL_BACK;
|
||||
}
|
||||
|
||||
inline GLenum LogicOp(Maxwell::LogicOperation operation) {
|
||||
inline GLenum LogicOp(Maxwell::LogicOp::Op operation) {
|
||||
switch (operation) {
|
||||
case Maxwell::LogicOperation::Clear:
|
||||
case Maxwell::LogicOp::Op::Clear:
|
||||
return GL_CLEAR;
|
||||
case Maxwell::LogicOperation::And:
|
||||
case Maxwell::LogicOp::Op::And:
|
||||
return GL_AND;
|
||||
case Maxwell::LogicOperation::AndReverse:
|
||||
case Maxwell::LogicOp::Op::AndReverse:
|
||||
return GL_AND_REVERSE;
|
||||
case Maxwell::LogicOperation::Copy:
|
||||
case Maxwell::LogicOp::Op::Copy:
|
||||
return GL_COPY;
|
||||
case Maxwell::LogicOperation::AndInverted:
|
||||
case Maxwell::LogicOp::Op::AndInverted:
|
||||
return GL_AND_INVERTED;
|
||||
case Maxwell::LogicOperation::NoOp:
|
||||
case Maxwell::LogicOp::Op::NoOp:
|
||||
return GL_NOOP;
|
||||
case Maxwell::LogicOperation::Xor:
|
||||
case Maxwell::LogicOp::Op::Xor:
|
||||
return GL_XOR;
|
||||
case Maxwell::LogicOperation::Or:
|
||||
case Maxwell::LogicOp::Op::Or:
|
||||
return GL_OR;
|
||||
case Maxwell::LogicOperation::Nor:
|
||||
case Maxwell::LogicOp::Op::Nor:
|
||||
return GL_NOR;
|
||||
case Maxwell::LogicOperation::Equiv:
|
||||
case Maxwell::LogicOp::Op::Equiv:
|
||||
return GL_EQUIV;
|
||||
case Maxwell::LogicOperation::Invert:
|
||||
case Maxwell::LogicOp::Op::Invert:
|
||||
return GL_INVERT;
|
||||
case Maxwell::LogicOperation::OrReverse:
|
||||
case Maxwell::LogicOp::Op::OrReverse:
|
||||
return GL_OR_REVERSE;
|
||||
case Maxwell::LogicOperation::CopyInverted:
|
||||
case Maxwell::LogicOp::Op::CopyInverted:
|
||||
return GL_COPY_INVERTED;
|
||||
case Maxwell::LogicOperation::OrInverted:
|
||||
case Maxwell::LogicOp::Op::OrInverted:
|
||||
return GL_OR_INVERTED;
|
||||
case Maxwell::LogicOperation::Nand:
|
||||
case Maxwell::LogicOp::Op::Nand:
|
||||
return GL_NAND;
|
||||
case Maxwell::LogicOperation::Set:
|
||||
case Maxwell::LogicOp::Op::Set:
|
||||
return GL_SET;
|
||||
}
|
||||
UNIMPLEMENTED_MSG("Unimplemented logic operation={}", operation);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue