From 6761e8639a07cca24ca88f66be7e1be5edd2f27c Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sun, 20 Nov 2016 04:06:21 +0100 Subject: [PATCH] Add palette support --- .../fixedfunction/drawtrianglecodegen.cpp | 46 +++++++++++++++---- .../fixedfunction/drawtrianglecodegen.h | 7 +++ src/r_compiler/llvmdrawers.cpp | 7 ++- src/r_compiler/llvmdrawers.h | 5 ++ src/r_poly.cpp | 9 ++-- src/r_poly_decal.cpp | 1 + src/r_poly_particle.cpp | 1 + src/r_poly_plane.cpp | 2 + src/r_poly_sky.cpp | 1 + src/r_poly_sprite.cpp | 1 + src/r_poly_triangle.cpp | 10 ++-- src/r_poly_triangle.h | 21 +++++++++ src/r_poly_wall.cpp | 1 + src/r_poly_wallsprite.cpp | 1 + 14 files changed, 94 insertions(+), 19 deletions(-) diff --git a/src/r_compiler/fixedfunction/drawtrianglecodegen.cpp b/src/r_compiler/fixedfunction/drawtrianglecodegen.cpp index fbbca7517a..c59992d3b8 100644 --- a/src/r_compiler/fixedfunction/drawtrianglecodegen.cpp +++ b/src/r_compiler/fixedfunction/drawtrianglecodegen.cpp @@ -258,7 +258,18 @@ void DrawTriangleCodegen::LoopBlockX() SSAFloat shade = 64.0f - (SSAFloat(light * 255 / 256) + 12.0f) * 32.0f / 128.0f; SSAFloat lightscale = SSAFloat::clamp((shade - SSAFloat::MIN(SSAFloat(24.0f), vis)) / 32.0f, SSAFloat(0.0f), SSAFloat(31.0f / 32.0f)); SSAInt diminishedlight = SSAInt(SSAFloat::clamp((1.0f - lightscale) * 256.0f + 0.5f, SSAFloat(0.0f), SSAFloat(256.0f)), false); - currentlight = is_fixed_light.select(light, diminishedlight); + + if (!truecolor) + { + SSAInt diminishedindex = SSAInt(lightscale * 32.0f, false); + SSAInt lightindex = SSAInt::MIN((256 - light) * 32 / 256, SSAInt(31)); + SSAInt colormapindex = is_fixed_light.select(lightindex, diminishedindex); + currentcolormap = Colormaps[colormapindex << 8]; + } + else + { + currentlight = is_fixed_light.select(light, diminishedlight); + } SetStencilBlock(x / 8 + y / 8 * stencilPitch); @@ -352,25 +363,32 @@ void DrawTriangleCodegen::LoopFullBlock() } else { - SSAVec4i pixels = buf.load_vec4ub(false); + SSAVec4i pixelsvec = buf.load_vec4ub(false); + SSAInt pixels[4] = + { + pixelsvec[0], + pixelsvec[1], + pixelsvec[2], + pixelsvec[3] + }; for (int sse = 0; sse < 4; sse++) { if (variant == TriDrawVariant::DrawSubsector || variant == TriDrawVariant::FillSubsector || variant == TriDrawVariant::FuzzSubsector) { SSABool subsectorTest = subsectorbuffer[ix].load(true) >= subsectorDepth; - pixels.insert(sse, subsectorTest.select(ProcessPixel8(pixels[sse], varying), pixels[sse])); + pixels[sse] = subsectorTest.select(ProcessPixel8(pixels[sse], varying), pixels[sse]); } else { - pixels.insert(sse, ProcessPixel8(pixels[sse], varying)); + pixels[sse] = ProcessPixel8(pixels[sse], varying); } for (int i = 0; i < TriVertex::NumVarying; i++) varying[i] = varying[i] + varyingStep[i]; } - buf.store_vec4ub(pixels); + buf.store_vec4ub(SSAVec4i(pixels[0], pixels[1], pixels[2], pixels[3])); } if (variant != TriDrawVariant::DrawSubsector && variant != TriDrawVariant::FillSubsector && variant != TriDrawVariant::FuzzSubsector) @@ -580,12 +598,16 @@ SSAInt DrawTriangleCodegen::ProcessPixel8(SSAInt bg, SSAInt *varying) if (variant == TriDrawVariant::FillNormal || variant == TriDrawVariant::FillSubsector || variant == TriDrawVariant::FuzzSubsector) { - return color; + return currentcolormap[color].load(true).zext_int(); } else { - SSAUByte fg = texturePixels[uvoffset].load(true); - return fg.zext_int(); + SSAInt index = texturePixels[uvoffset].load(true).zext_int(); + SSAInt fg = currentcolormap[index].load(true).zext_int(); + if (blendmode != TriBlendMode::AlphaBlend) + return fg; + else + return (index == SSAInt(0)).select(bg, fg); } } @@ -659,6 +681,14 @@ void DrawTriangleCodegen::LoadArgs(SSAValue args, SSAValue thread_data) stencilTestValue = args[0][17].load(true); stencilWriteValue = args[0][18].load(true); subsectorGBuffer = args[0][19].load(true); + if (!truecolor) + { + Colormaps = args[0][20].load(true); + RGB32k = args[0][21].load(true); + Col2RGB8 = args[0][22].load(true); + Col2RGB8_LessPrecision = args[0][23].load(true); + Col2RGB8_Inverse = args[0][24].load(true); + } thread.core = thread_data[0][0].load(true); thread.num_cores = thread_data[0][1].load(true); diff --git a/src/r_compiler/fixedfunction/drawtrianglecodegen.h b/src/r_compiler/fixedfunction/drawtrianglecodegen.h index e4c22d49cd..d2ff95e023 100644 --- a/src/r_compiler/fixedfunction/drawtrianglecodegen.h +++ b/src/r_compiler/fixedfunction/drawtrianglecodegen.h @@ -107,6 +107,12 @@ private: SSAUByte stencilWriteValue; SSAIntPtr subsectorGBuffer; + SSAUBytePtr Colormaps; + SSAUBytePtr RGB32k; + SSAIntPtr Col2RGB8; + SSAIntPtr Col2RGB8_LessPrecision; + SSAIntPtr Col2RGB8_Inverse; + SSAWorkerThread thread; // Block size, standard 8x8 (must be power of two) @@ -126,6 +132,7 @@ private: SSAInt x, y; SSAInt x0, x1, y0, y1; SSAInt currentlight; + SSAUBytePtr currentcolormap; SSAInt varyingPos[TriVertex::NumVarying]; SSAInt varyingStepPos[TriVertex::NumVarying]; SSAInt varyingStartStepX[TriVertex::NumVarying]; diff --git a/src/r_compiler/llvmdrawers.cpp b/src/r_compiler/llvmdrawers.cpp index 913e5d9b78..869a24c2ce 100644 --- a/src/r_compiler/llvmdrawers.cpp +++ b/src/r_compiler/llvmdrawers.cpp @@ -127,7 +127,7 @@ LLVMDrawers *LLVMDrawers::Instance() LLVMDrawersImpl::LLVMDrawersImpl() { - int version = 2; // Increment this number if the drawer codegen is modified (forces recreation of the module). + int version = 3; // Increment this number if the drawer codegen is modified (forces recreation of the module). std::string targetCPU = mProgram.GetTargetCPU(); bool loaded = mProgram.LoadCachedModule(version, targetCPU); if (!loaded) @@ -582,6 +582,11 @@ llvm::Type *LLVMDrawersImpl::GetTriDrawTriangleArgs(llvm::LLVMContext &context) elements.push_back(llvm::Type::getInt8Ty(context)); // uint8_t stencilTestValue; elements.push_back(llvm::Type::getInt8Ty(context)); // uint8_t stencilWriteValue; elements.push_back(llvm::Type::getInt32PtrTy(context)); // uint32_t *subsectorGBuffer; + elements.push_back(llvm::Type::getInt8PtrTy(context)); // const uint8_t *colormaps; + elements.push_back(llvm::Type::getInt8PtrTy(context)); // const uint8_t *RGB32k; + elements.push_back(llvm::Type::getInt32PtrTy(context)); // const uint32_t *Col2RGB8; + elements.push_back(llvm::Type::getInt32PtrTy(context)); // const uint32_t *Col2RGB8_LessPrecision; + elements.push_back(llvm::Type::getInt32PtrTy(context)); // const uint32_t *Col2RGB8_Inverse; return llvm::StructType::create(context, elements, "TriDrawTriangle", false)->getPointerTo(); } diff --git a/src/r_compiler/llvmdrawers.h b/src/r_compiler/llvmdrawers.h index 1db2f5b2a5..873f98c73c 100644 --- a/src/r_compiler/llvmdrawers.h +++ b/src/r_compiler/llvmdrawers.h @@ -258,6 +258,11 @@ struct TriDrawTriangleArgs uint8_t stencilTestValue; uint8_t stencilWriteValue; uint32_t *subsectorGBuffer; + const uint8_t *colormaps; + const uint8_t *RGB32k; + const uint32_t *Col2RGB8; + const uint32_t *Col2RGB8_LessPrecision; + const uint32_t *Col2RGB8_Inverse; }; enum class TriDrawVariant diff --git a/src/r_poly.cpp b/src/r_poly.cpp index 4dc90027d0..680d77c523 100644 --- a/src/r_poly.cpp +++ b/src/r_poly.cpp @@ -36,9 +36,6 @@ void InitGLRMapinfoData(); void RenderPolyScene::Render() { - if (!r_swtruecolor) // Disable pal rendering for now - return; - ClearBuffers(); SetSceneViewport(); SetupPerspectiveMatrix(); @@ -63,8 +60,8 @@ void RenderPolyScene::ClearBuffers() SectorSpriteRanges.resize(numsectors); SortedSprites.clear(); TranslucentObjects.clear(); - PolyStencilBuffer::Instance()->Clear(screen->GetWidth(), screen->GetHeight(), 0); - PolySubsectorGBuffer::Instance()->Resize(screen->GetPitch(), screen->GetHeight()); + PolyStencilBuffer::Instance()->Clear(RenderTarget->GetWidth(), RenderTarget->GetHeight(), 0); + PolySubsectorGBuffer::Instance()->Resize(RenderTarget->GetPitch(), RenderTarget->GetHeight()); NextSubsectorDepth = 0; } @@ -77,7 +74,7 @@ void RenderPolyScene::SetSceneViewport() height = (screenblocks*SCREENHEIGHT / 10) & ~7; int bottom = SCREENHEIGHT - (height + viewwindowy - ((height - viewheight) / 2)); - PolyTriangleDrawer::set_viewport(viewwindowx, SCREENHEIGHT - bottom - height, viewwidth, height, screen); + PolyTriangleDrawer::set_viewport(viewwindowx, SCREENHEIGHT - bottom - height, viewwidth, height, RenderTarget); } void RenderPolyScene::SetupPerspectiveMatrix() diff --git a/src/r_poly_decal.cpp b/src/r_poly_decal.cpp index 52caae7e2e..fa77b25a45 100644 --- a/src/r_poly_decal.cpp +++ b/src/r_poly_decal.cpp @@ -152,6 +152,7 @@ void RenderPolyDecal::Render(const TriMatrix &worldToClip, DBaseDecal *decal, co args.stenciltestvalue = 0; args.stencilwritevalue = 1; args.SetTexture(tex); + args.SetColormap(line->frontsector->ColorMap); //mode = R_SetPatchStyle (decal->RenderStyle, (float)decal->Alpha, decal->Translation, decal->AlphaColor); PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector, TriBlendMode::Shaded); } diff --git a/src/r_poly_particle.cpp b/src/r_poly_particle.cpp index 8448c8f32b..619b3e146c 100644 --- a/src/r_poly_particle.cpp +++ b/src/r_poly_particle.cpp @@ -94,5 +94,6 @@ void RenderPolyParticle::Render(const TriMatrix &worldToClip, particle_t *partic args.ccw = true; args.stenciltestvalue = 0; args.stencilwritevalue = 1; + args.SetColormap(sub->sector->ColorMap); PolyTriangleDrawer::draw(args, TriDrawVariant::FillSubsector, TriBlendMode::AlphaBlend); } diff --git a/src/r_poly_plane.cpp b/src/r_poly_plane.cpp index a68a4b5689..a64dfaaf57 100644 --- a/src/r_poly_plane.cpp +++ b/src/r_poly_plane.cpp @@ -140,6 +140,7 @@ void RenderPolyPlane::Render3DFloor(const TriMatrix &worldToClip, subsector_t *s args.stenciltestvalue = 0; args.stencilwritevalue = 1; args.SetTexture(tex); + args.SetColormap(sub->sector->ColorMap); PolyTriangleDrawer::draw(args, TriDrawVariant::DrawNormal, TriBlendMode::Copy); PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil, TriBlendMode::Copy); } @@ -231,6 +232,7 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, subsector_t *sub, uin args.ccw = ccw; args.stenciltestvalue = 0; args.stencilwritevalue = 1; + args.SetColormap(frontsector->ColorMap); if (!isSky) { diff --git a/src/r_poly_sky.cpp b/src/r_poly_sky.cpp index a60b3f460e..a8e7b23d6e 100644 --- a/src/r_poly_sky.cpp +++ b/src/r_poly_sky.cpp @@ -63,6 +63,7 @@ void PolySkyDome::Render(const TriMatrix &worldToClip) args.stenciltestvalue = 255; args.stencilwritevalue = 1; args.SetTexture(frontskytex); + args.SetColormap(&NormalLight); RenderCapColorRow(args, frontskytex, 0, false); RenderCapColorRow(args, frontskytex, rc, true); diff --git a/src/r_poly_sprite.cpp b/src/r_poly_sprite.cpp index 84ff8e2213..737707c74a 100644 --- a/src/r_poly_sprite.cpp +++ b/src/r_poly_sprite.cpp @@ -136,6 +136,7 @@ void RenderPolySprite::Render(const TriMatrix &worldToClip, AActor *thing, subse args.stenciltestvalue = 0; args.stencilwritevalue = 1; args.SetTexture(tex, thing->Translation); + args.SetColormap(sub->sector->ColorMap); if (args.translation) PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector, TriBlendMode::TranslateAlphaBlend); diff --git a/src/r_poly_triangle.cpp b/src/r_poly_triangle.cpp index 5574251e61..a00ea90eb3 100644 --- a/src/r_poly_triangle.cpp +++ b/src/r_poly_triangle.cpp @@ -70,10 +70,7 @@ void PolyTriangleDrawer::set_viewport(int x, int y, int width, int height, DCanv void PolyTriangleDrawer::draw(const PolyDrawArgs &args, TriDrawVariant variant, TriBlendMode blendmode) { - if (dest_bgra) - DrawerCommandQueue::QueueCommand(args, variant, blendmode); - else - draw_arrays(args, variant, blendmode, nullptr); + DrawerCommandQueue::QueueCommand(args, variant, blendmode); } void PolyTriangleDrawer::draw_arrays(const PolyDrawArgs &drawargs, TriDrawVariant variant, TriBlendMode blendmode, WorkerThreadData *thread) @@ -113,6 +110,11 @@ void PolyTriangleDrawer::draw_arrays(const PolyDrawArgs &drawargs, TriDrawVarian args.stencilValues = PolyStencilBuffer::Instance()->Values(); args.stencilMasks = PolyStencilBuffer::Instance()->Masks(); args.subsectorGBuffer = PolySubsectorGBuffer::Instance()->Values(); + args.colormaps = drawargs.colormaps; + args.RGB32k = RGB32k.All; + args.Col2RGB8 = (const uint32_t*)Col2RGB8; + args.Col2RGB8_Inverse = (const uint32_t*)Col2RGB8_Inverse; + args.Col2RGB8_LessPrecision = (const uint32_t*)Col2RGB8_LessPrecision; bool ccw = drawargs.ccw; const TriVertex *vinput = drawargs.vinput; diff --git a/src/r_poly_triangle.h b/src/r_poly_triangle.h index db6719de90..5736e2c9d2 100644 --- a/src/r_poly_triangle.h +++ b/src/r_poly_triangle.h @@ -26,6 +26,7 @@ #include "r_thread.h" #include "r_compiler/llvmdrawers.h" #include "r_data/r_translate.h" +#include "r_data/colormaps.h" class FTexture; @@ -53,6 +54,7 @@ public: const uint8_t *translation = nullptr; uint8_t stenciltestvalue = 0; uint8_t stencilwritevalue = 0; + const uint8_t *colormaps = nullptr; void SetTexture(FTexture *texture) { @@ -86,6 +88,25 @@ public: SetTexture(texture); } + + void SetColormap(FSWColormap *base_colormap) + { + uniforms.light_red = base_colormap->Color.r * 256 / 255; + uniforms.light_green = base_colormap->Color.g * 256 / 255; + uniforms.light_blue = base_colormap->Color.b * 256 / 255; + uniforms.light_alpha = base_colormap->Color.a * 256 / 255; + uniforms.fade_red = base_colormap->Fade.r; + uniforms.fade_green = base_colormap->Fade.g; + uniforms.fade_blue = base_colormap->Fade.b; + uniforms.fade_alpha = base_colormap->Fade.a; + uniforms.desaturate = MIN(abs(base_colormap->Desaturate), 255) * 255 / 256; + bool simple_shade = (base_colormap->Color.d == 0x00ffffff && base_colormap->Fade.d == 0x00000000 && base_colormap->Desaturate == 0); + if (simple_shade) + uniforms.flags |= TriUniforms::simple_shade; + else + uniforms.flags &= ~TriUniforms::simple_shade; + colormaps = base_colormap->Maps; + } }; class PolyTriangleDrawer diff --git a/src/r_poly_wall.cpp b/src/r_poly_wall.cpp index f0eb33c32f..92c669ebf8 100644 --- a/src/r_poly_wall.cpp +++ b/src/r_poly_wall.cpp @@ -190,6 +190,7 @@ void RenderPolyWall::Render(const TriMatrix &worldToClip) args.stenciltestvalue = 0; args.stencilwritevalue = 1; args.SetTexture(tex); + args.SetColormap(Line->frontsector->ColorMap); if (!Masked) { diff --git a/src/r_poly_wallsprite.cpp b/src/r_poly_wallsprite.cpp index cd331dcb52..6ed009c333 100644 --- a/src/r_poly_wallsprite.cpp +++ b/src/r_poly_wallsprite.cpp @@ -121,5 +121,6 @@ void RenderPolyWallSprite::Render(const TriMatrix &worldToClip, AActor *thing, s args.stenciltestvalue = 0; args.stencilwritevalue = 1; args.SetTexture(tex); + args.SetColormap(sub->sector->ColorMap); PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector, TriBlendMode::AlphaBlend); }