mirror of
https://github.com/libretro/ppsspp.git
synced 2025-02-13 21:29:40 +00:00
Draw: Preliminary stencil implementation. Two-sided only implemented for Vulkan.
This commit is contained in:
parent
cbf4e5f38c
commit
10e4d4db14
@ -84,6 +84,17 @@ enum BlendFactor : int {
|
||||
FIXED_COLOR,
|
||||
};
|
||||
|
||||
enum class StencilOp {
|
||||
KEEP = 0,
|
||||
ZERO = 1,
|
||||
REPLACE = 2,
|
||||
INCREMENT_AND_CLAMP = 3,
|
||||
DECREMENT_AND_CLAMP = 4,
|
||||
INVERT = 5,
|
||||
INCREMENT_AND_WRAP = 6,
|
||||
DECREMENT_AND_WRAP = 7,
|
||||
};
|
||||
|
||||
enum class TextureFilter : int {
|
||||
NEAREST,
|
||||
LINEAR,
|
||||
@ -205,6 +216,57 @@ enum class DataFormat : uint8_t {
|
||||
D32F_S8,
|
||||
};
|
||||
|
||||
enum class ShaderStage {
|
||||
VERTEX,
|
||||
FRAGMENT,
|
||||
GEOMETRY,
|
||||
CONTROL, // HULL
|
||||
EVALUATION, // DOMAIN
|
||||
COMPUTE,
|
||||
};
|
||||
|
||||
enum class CullMode : uint8_t {
|
||||
NONE,
|
||||
FRONT,
|
||||
BACK,
|
||||
FRONT_AND_BACK, // Not supported on D3D9
|
||||
};
|
||||
|
||||
enum class Facing {
|
||||
CCW,
|
||||
CW,
|
||||
};
|
||||
|
||||
enum BorderColor {
|
||||
DONT_CARE,
|
||||
TRANSPARENT_BLACK,
|
||||
OPAQUE_BLACK,
|
||||
OPAQUE_WHITE,
|
||||
};
|
||||
|
||||
enum {
|
||||
COLOR_MASK_R = 1,
|
||||
COLOR_MASK_G = 2,
|
||||
COLOR_MASK_B = 4,
|
||||
COLOR_MASK_A = 8,
|
||||
};
|
||||
|
||||
enum class TextureAddressMode {
|
||||
REPEAT,
|
||||
REPEAT_MIRROR,
|
||||
CLAMP_TO_EDGE,
|
||||
CLAMP_TO_BORDER,
|
||||
};
|
||||
|
||||
enum class ShaderLanguage {
|
||||
GLSL_ES_200,
|
||||
GLSL_ES_300,
|
||||
GLSL_410,
|
||||
GLSL_VULKAN,
|
||||
HLSL_D3D9,
|
||||
HLSL_D3D11,
|
||||
};
|
||||
|
||||
enum ImageFileType {
|
||||
PNG,
|
||||
JPEG,
|
||||
@ -299,24 +361,6 @@ struct InputLayoutDesc {
|
||||
|
||||
class InputLayout : public RefCountedObject { };
|
||||
|
||||
enum class ShaderStage {
|
||||
VERTEX,
|
||||
FRAGMENT,
|
||||
GEOMETRY,
|
||||
CONTROL, // HULL
|
||||
EVALUATION, // DOMAIN
|
||||
COMPUTE,
|
||||
};
|
||||
|
||||
enum class ShaderLanguage {
|
||||
GLSL_ES_200,
|
||||
GLSL_ES_300,
|
||||
GLSL_410,
|
||||
GLSL_VULKAN,
|
||||
HLSL_D3D9,
|
||||
HLSL_D3D11,
|
||||
};
|
||||
|
||||
enum class UniformType : int8_t {
|
||||
FLOAT, FLOAT2, FLOAT3, FLOAT4,
|
||||
MATRIX4X4,
|
||||
@ -350,11 +394,23 @@ public:
|
||||
|
||||
class RasterState : public RefCountedObject {};
|
||||
|
||||
struct StencilSide {
|
||||
StencilOp failOp;
|
||||
StencilOp passOp;
|
||||
StencilOp depthFailOp;
|
||||
Comparison compareOp;
|
||||
uint8_t compareMask;
|
||||
uint8_t writeMask;
|
||||
uint8_t reference;
|
||||
};
|
||||
|
||||
struct DepthStencilStateDesc {
|
||||
bool depthTestEnabled;
|
||||
bool depthWriteEnabled;
|
||||
Comparison depthCompare;
|
||||
// Ignore stencil for now, will need soon.
|
||||
bool stencilEnabled;
|
||||
StencilSide front;
|
||||
StencilSide back;
|
||||
};
|
||||
|
||||
struct BlendStateDesc {
|
||||
@ -370,27 +426,6 @@ struct BlendStateDesc {
|
||||
LogicOp logicOp;
|
||||
};
|
||||
|
||||
enum {
|
||||
COLOR_MASK_R = 1,
|
||||
COLOR_MASK_G = 2,
|
||||
COLOR_MASK_B = 4,
|
||||
COLOR_MASK_A = 8,
|
||||
};
|
||||
|
||||
enum BorderColor {
|
||||
DONT_CARE,
|
||||
TRANSPARENT_BLACK,
|
||||
OPAQUE_BLACK,
|
||||
OPAQUE_WHITE,
|
||||
};
|
||||
|
||||
enum class TextureAddressMode {
|
||||
REPEAT,
|
||||
REPEAT_MIRROR,
|
||||
CLAMP_TO_EDGE,
|
||||
CLAMP_TO_BORDER,
|
||||
};
|
||||
|
||||
struct SamplerStateDesc {
|
||||
TextureFilter magFilter;
|
||||
TextureFilter minFilter;
|
||||
@ -405,18 +440,6 @@ struct SamplerStateDesc {
|
||||
BorderColor borderColor;
|
||||
};
|
||||
|
||||
enum class CullMode : uint8_t {
|
||||
NONE,
|
||||
FRONT,
|
||||
BACK,
|
||||
FRONT_AND_BACK, // Not supported on D3D9
|
||||
};
|
||||
|
||||
enum class Facing {
|
||||
CCW,
|
||||
CW,
|
||||
};
|
||||
|
||||
struct RasterStateDesc {
|
||||
CullMode cull;
|
||||
Facing facing;
|
||||
|
@ -83,6 +83,17 @@ static const D3DPRIMITIVETYPE primToD3D9[] = {
|
||||
D3DPT_POINTLIST,
|
||||
};
|
||||
|
||||
static const D3DSTENCILOP stencilOpToD3D9[] = {
|
||||
D3DSTENCILOP_KEEP,
|
||||
D3DSTENCILOP_ZERO,
|
||||
D3DSTENCILOP_REPLACE,
|
||||
D3DSTENCILOP_INCRSAT,
|
||||
D3DSTENCILOP_DECRSAT,
|
||||
D3DSTENCILOP_INVERT,
|
||||
D3DSTENCILOP_INCR,
|
||||
D3DSTENCILOP_DECR,
|
||||
};
|
||||
|
||||
static const int primCountDivisor[] = {
|
||||
1,
|
||||
2,
|
||||
@ -101,11 +112,30 @@ public:
|
||||
BOOL depthTestEnabled;
|
||||
BOOL depthWriteEnabled;
|
||||
D3DCMPFUNC depthCompare;
|
||||
|
||||
BOOL stencilEnabled;
|
||||
D3DSTENCILOP stencilFail;
|
||||
D3DSTENCILOP stencilZFail;
|
||||
D3DSTENCILOP stencilPass;
|
||||
D3DCMPFUNC stencilCompareOp;
|
||||
uint8_t stencilReference;
|
||||
uint8_t stencilCompareMask;
|
||||
uint8_t stencilWriteMask;
|
||||
void Apply(LPDIRECT3DDEVICE9 device) {
|
||||
device->SetRenderState(D3DRS_ZENABLE, depthTestEnabled);
|
||||
device->SetRenderState(D3DRS_ZWRITEENABLE, depthWriteEnabled);
|
||||
device->SetRenderState(D3DRS_ZFUNC, depthCompare);
|
||||
if (depthTestEnabled) {
|
||||
device->SetRenderState(D3DRS_ZWRITEENABLE, depthWriteEnabled);
|
||||
device->SetRenderState(D3DRS_ZFUNC, depthCompare);
|
||||
}
|
||||
device->SetRenderState(D3DRS_STENCILENABLE, stencilEnabled);
|
||||
if (stencilEnabled) {
|
||||
device->SetRenderState(D3DRS_STENCILFAIL, stencilFail);
|
||||
device->SetRenderState(D3DRS_STENCILZFAIL, stencilZFail);
|
||||
device->SetRenderState(D3DRS_STENCILPASS, stencilPass);
|
||||
device->SetRenderState(D3DRS_STENCILFUNC, stencilCompareOp);
|
||||
device->SetRenderState(D3DRS_STENCILMASK, stencilCompareMask);
|
||||
device->SetRenderState(D3DRS_STENCILREF, stencilReference);
|
||||
device->SetRenderState(D3DRS_STENCILWRITEMASK, stencilWriteMask);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -591,6 +621,14 @@ DepthStencilState *D3D9Context::CreateDepthStencilState(const DepthStencilStateD
|
||||
ds->depthTestEnabled = desc.depthTestEnabled;
|
||||
ds->depthWriteEnabled = desc.depthWriteEnabled;
|
||||
ds->depthCompare = compareToD3D9[(int)desc.depthCompare];
|
||||
ds->stencilEnabled = desc.stencilEnabled;
|
||||
ds->stencilCompareOp = compareToD3D9[(int)desc.front.compareOp];
|
||||
ds->stencilPass = stencilOpToD3D9[(int)desc.front.passOp];
|
||||
ds->stencilFail = stencilOpToD3D9[(int)desc.front.failOp];
|
||||
ds->stencilZFail = stencilOpToD3D9[(int)desc.front.depthFailOp];
|
||||
ds->stencilWriteMask = desc.front.writeMask;
|
||||
ds->stencilReference = desc.front.reference;
|
||||
ds->stencilCompareMask = desc.front.compareMask;
|
||||
return ds;
|
||||
}
|
||||
|
||||
|
@ -83,6 +83,17 @@ static const unsigned short logicOpToGL[] = {
|
||||
};
|
||||
#endif
|
||||
|
||||
static const GLuint stencilOpToGL[8] = {
|
||||
GL_KEEP,
|
||||
GL_ZERO,
|
||||
GL_REPLACE,
|
||||
GL_INCR,
|
||||
GL_DECR,
|
||||
GL_INVERT,
|
||||
GL_INCR_WRAP,
|
||||
GL_DECR_WRAP,
|
||||
};
|
||||
|
||||
static const unsigned short primToGL[] = {
|
||||
GL_POINTS,
|
||||
GL_LINES,
|
||||
@ -166,7 +177,15 @@ public:
|
||||
bool depthTestEnabled;
|
||||
bool depthWriteEnabled;
|
||||
GLuint depthComp;
|
||||
// bool stencilTestEnabled; TODO
|
||||
// TODO: Two-sided
|
||||
GLboolean stencilEnabled;
|
||||
GLuint stencilFail;
|
||||
GLuint stencilZFail;
|
||||
GLuint stencilPass;
|
||||
GLuint stencilCompareOp;
|
||||
uint8_t stencilReference;
|
||||
uint8_t stencilCompareMask;
|
||||
uint8_t stencilWriteMask;
|
||||
|
||||
void Apply() {
|
||||
if (depthTestEnabled) {
|
||||
@ -176,6 +195,14 @@ public:
|
||||
} else {
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
}
|
||||
if (stencilEnabled) {
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
glStencilOpSeparate(GL_FRONT_AND_BACK, stencilFail, stencilZFail, stencilPass);
|
||||
glStencilFuncSeparate(GL_FRONT_AND_BACK, stencilCompareOp, stencilReference, stencilCompareMask);
|
||||
glStencilMaskSeparate(GL_FRONT_AND_BACK, stencilWriteMask);
|
||||
} else {
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
}
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
}
|
||||
};
|
||||
@ -737,6 +764,14 @@ DepthStencilState *OpenGLContext::CreateDepthStencilState(const DepthStencilStat
|
||||
ds->depthTestEnabled = desc.depthTestEnabled;
|
||||
ds->depthWriteEnabled = desc.depthWriteEnabled;
|
||||
ds->depthComp = compToGL[(int)desc.depthCompare];
|
||||
ds->stencilEnabled = desc.stencilEnabled;
|
||||
ds->stencilCompareOp = compToGL[(int)desc.front.compareOp];
|
||||
ds->stencilPass = stencilOpToGL[(int)desc.front.passOp];
|
||||
ds->stencilFail = stencilOpToGL[(int)desc.front.failOp];
|
||||
ds->stencilZFail = stencilOpToGL[(int)desc.front.depthFailOp];
|
||||
ds->stencilWriteMask = desc.front.writeMask;
|
||||
ds->stencilReference = desc.front.reference;
|
||||
ds->stencilCompareMask = desc.front.compareMask;
|
||||
return ds;
|
||||
}
|
||||
|
||||
|
@ -112,6 +112,18 @@ static const VkPrimitiveTopology primToVK[] = {
|
||||
VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY,
|
||||
};
|
||||
|
||||
|
||||
static const VkStencilOp stencilOpToVK[8] = {
|
||||
VK_STENCIL_OP_KEEP,
|
||||
VK_STENCIL_OP_ZERO,
|
||||
VK_STENCIL_OP_REPLACE,
|
||||
VK_STENCIL_OP_INCREMENT_AND_CLAMP,
|
||||
VK_STENCIL_OP_DECREMENT_AND_CLAMP,
|
||||
VK_STENCIL_OP_INVERT,
|
||||
VK_STENCIL_OP_INCREMENT_AND_WRAP,
|
||||
VK_STENCIL_OP_DECREMENT_AND_WRAP,
|
||||
};
|
||||
|
||||
static inline void Uint8x4ToFloat4(uint32_t u, float f[4]) {
|
||||
f[0] = ((u >> 0) & 0xFF) * (1.0f / 255.0f);
|
||||
f[1] = ((u >> 8) & 0xFF) * (1.0f / 255.0f);
|
||||
@ -121,25 +133,13 @@ static inline void Uint8x4ToFloat4(uint32_t u, float f[4]) {
|
||||
|
||||
class VKBlendState : public BlendState {
|
||||
public:
|
||||
VkPipelineColorBlendStateCreateInfo info{};
|
||||
VkPipelineColorBlendStateCreateInfo info{ VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO };
|
||||
std::vector<VkPipelineColorBlendAttachmentState> attachments;
|
||||
};
|
||||
|
||||
class VKDepthStencilState : public DepthStencilState {
|
||||
public:
|
||||
bool depthTestEnabled;
|
||||
bool depthWriteEnabled;
|
||||
VkCompareOp depthComp;
|
||||
|
||||
void ToVulkan(VkPipelineDepthStencilStateCreateInfo *info) const {
|
||||
memset(info, 0, sizeof(*info));
|
||||
info->sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
|
||||
info->depthCompareOp = depthComp;
|
||||
info->depthTestEnable = depthTestEnabled;
|
||||
info->depthWriteEnable = depthWriteEnabled;
|
||||
info->stencilTestEnable = false;
|
||||
info->depthBoundsTestEnable = false;
|
||||
}
|
||||
VkPipelineDepthStencilStateCreateInfo info{ VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO };
|
||||
};
|
||||
|
||||
class VKRasterState : public RasterState {
|
||||
@ -819,9 +819,6 @@ Pipeline *VKContext::CreateGraphicsPipeline(const PipelineDesc &desc) {
|
||||
stage.flags = 0;
|
||||
}
|
||||
|
||||
VkPipelineDepthStencilStateCreateInfo depthStencil;
|
||||
depth->ToVulkan(&depthStencil);
|
||||
|
||||
VkPipelineInputAssemblyStateCreateInfo inputAssembly = { VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO };
|
||||
inputAssembly.topology = primToVK[(int)desc.prim];
|
||||
inputAssembly.primitiveRestartEnable = false;
|
||||
@ -852,7 +849,7 @@ Pipeline *VKContext::CreateGraphicsPipeline(const PipelineDesc &desc) {
|
||||
info.stageCount = (uint32_t)stages.size();
|
||||
info.pStages = stages.data();
|
||||
info.pColorBlendState = &blend->info;
|
||||
info.pDepthStencilState = &depthStencil;
|
||||
info.pDepthStencilState = &depth->info;
|
||||
info.pDynamicState = &dynamicInfo;
|
||||
info.pInputAssemblyState = &inputAssembly;
|
||||
info.pTessellationState = nullptr;
|
||||
@ -957,11 +954,27 @@ void VKTexture::Finalize(int zim_flags) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
inline void CopySide(VkStencilOpState &dest, const StencilSide &src) {
|
||||
dest.compareMask = src.compareMask;
|
||||
dest.reference = src.reference;
|
||||
dest.writeMask = src.writeMask;
|
||||
dest.compareOp = compToVK[(int)src.compareOp];
|
||||
dest.failOp = stencilOpToVK[(int)src.failOp];
|
||||
dest.passOp = stencilOpToVK[(int)src.passOp];
|
||||
dest.depthFailOp = stencilOpToVK[(int)src.depthFailOp];
|
||||
}
|
||||
|
||||
DepthStencilState *VKContext::CreateDepthStencilState(const DepthStencilStateDesc &desc) {
|
||||
VKDepthStencilState *ds = new VKDepthStencilState();
|
||||
ds->depthTestEnabled = desc.depthTestEnabled;
|
||||
ds->depthWriteEnabled = desc.depthWriteEnabled;
|
||||
ds->depthComp = compToVK[(int)desc.depthCompare];
|
||||
ds->info.depthCompareOp = compToVK[(int)desc.depthCompare];
|
||||
ds->info.depthTestEnable = desc.depthTestEnabled;
|
||||
ds->info.depthWriteEnable = desc.depthWriteEnabled;
|
||||
ds->info.stencilTestEnable = false;
|
||||
ds->info.depthBoundsTestEnable = false;
|
||||
if (ds->info.stencilTestEnable) {
|
||||
CopySide(ds->info.front, desc.front);
|
||||
CopySide(ds->info.back, desc.back);
|
||||
}
|
||||
return ds;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user