diff --git a/changelog/12628.feature.rst b/changelog/12628.feature.rst
new file mode 100644
index 00000000000..b565cb89938
--- /dev/null
+++ b/changelog/12628.feature.rst
@@ -0,0 +1,3 @@
+Existing parameters (argname and case index) are passed to hook and idfn for parameterized test ID creation.
+
+-- by :user:`nicoloborghi`
diff --git a/src/_pytest/fixtures.py b/src/_pytest/fixtures.py
index 7d0b40b150a..6baf9e76e2a 100644
--- a/src/_pytest/fixtures.py
+++ b/src/_pytest/fixtures.py
@@ -955,7 +955,9 @@ def __init__(
         func: _FixtureFunc[FixtureValue],
         scope: Scope | _ScopeName | Callable[[str, Config], _ScopeName] | None,
         params: Sequence[object] | None,
-        ids: tuple[object | None, ...] | Callable[[Any], object | None] | None = None,
+        ids: tuple[object | None, ...]
+        | Callable[[Any, str, int], object | None]
+        | None = None,
         *,
         _ispytest: bool = False,
     ) -> None:
@@ -1180,7 +1182,9 @@ class FixtureFunctionMarker:
     scope: _ScopeName | Callable[[str, Config], _ScopeName]
     params: tuple[object, ...] | None
     autouse: bool = False
-    ids: tuple[object | None, ...] | Callable[[Any], object | None] | None = None
+    ids: tuple[object | None, ...] | Callable[[Any, str, int], object | None] | None = (
+        None
+    )
     name: str | None = None
 
     _ispytest: dataclasses.InitVar[bool] = False
@@ -1222,7 +1226,9 @@ def fixture(
     scope: _ScopeName | Callable[[str, Config], _ScopeName] = ...,
     params: Iterable[object] | None = ...,
     autouse: bool = ...,
-    ids: Sequence[object | None] | Callable[[Any], object | None] | None = ...,
+    ids: Sequence[object | None]
+    | Callable[[Any, str, int], object | None]
+    | None = ...,
     name: str | None = ...,
 ) -> FixtureFunction: ...
 
@@ -1234,7 +1240,9 @@ def fixture(
     scope: _ScopeName | Callable[[str, Config], _ScopeName] = ...,
     params: Iterable[object] | None = ...,
     autouse: bool = ...,
-    ids: Sequence[object | None] | Callable[[Any], object | None] | None = ...,
+    ids: Sequence[object | None]
+    | Callable[[Any, str, int], object | None]
+    | None = ...,
     name: str | None = None,
 ) -> FixtureFunctionMarker: ...
 
@@ -1245,7 +1253,9 @@ def fixture(
     scope: _ScopeName | Callable[[str, Config], _ScopeName] = "function",
     params: Iterable[object] | None = None,
     autouse: bool = False,
-    ids: Sequence[object | None] | Callable[[Any], object | None] | None = None,
+    ids: Sequence[object | None]
+    | Callable[[Any, str, int], object | None]
+    | None = None,
     name: str | None = None,
 ) -> FixtureFunctionMarker | FixtureFunction:
     """Decorator to mark a fixture factory function.
@@ -1633,7 +1643,9 @@ def _register_fixture(
         nodeid: str | None,
         scope: Scope | _ScopeName | Callable[[str, Config], _ScopeName] = "function",
         params: Sequence[object] | None = None,
-        ids: tuple[object | None, ...] | Callable[[Any], object | None] | None = None,
+        ids: tuple[object | None, ...]
+        | Callable[[Any, str, int], object | None]
+        | None = None,
         autouse: bool = False,
     ) -> None:
         """Register a fixture
diff --git a/src/_pytest/hookspec.py b/src/_pytest/hookspec.py
index 99614899994..791c75046b4 100644
--- a/src/_pytest/hookspec.py
+++ b/src/_pytest/hookspec.py
@@ -588,7 +588,9 @@ def pytest_generate_tests(metafunc: Metafunc) -> None:
 
 
 @hookspec(firstresult=True)
-def pytest_make_parametrize_id(config: Config, val: object, argname: str) -> str | None:
+def pytest_make_parametrize_id(
+    config: Config, val: object, argname: str, idx: int
+) -> str | None:
     """Return a user-friendly string representation of the given ``val``
     that will be used by @pytest.mark.parametrize calls, or None if the hook
     doesn't know about ``val``.
@@ -600,6 +602,7 @@ def pytest_make_parametrize_id(config: Config, val: object, argname: str) -> str
     :param config: The pytest config object.
     :param val: The parametrized value.
     :param argname: The automatic parameter name produced by pytest.
+    :param idx: The iteration number of parameterized tests as calculated by pytest.
 
     Use in conftest plugins
     =======================
diff --git a/src/_pytest/python.py b/src/_pytest/python.py
index 9182ce7dfe9..6ff114d2285 100644
--- a/src/_pytest/python.py
+++ b/src/_pytest/python.py
@@ -869,7 +869,7 @@ class IdMaker:
     parametersets: Sequence[ParameterSet]
     # Optionally, a user-provided callable to make IDs for parameters in a
     # ParameterSet.
-    idfn: Callable[[Any], object | None] | None
+    idfn: Callable[[Any, str, int], object | None] | None
     # Optionally, explicit IDs for ParameterSets by index.
     ids: Sequence[object | None] | None
     # Optionally, the pytest config.
@@ -939,7 +939,7 @@ def _idval(self, val: object, argname: str, idx: int) -> str:
         idval = self._idval_from_function(val, argname, idx)
         if idval is not None:
             return idval
-        idval = self._idval_from_hook(val, argname)
+        idval = self._idval_from_hook(val, argname, idx)
         if idval is not None:
             return idval
         idval = self._idval_from_value(val)
@@ -953,7 +953,7 @@ def _idval_from_function(self, val: object, argname: str, idx: int) -> str | Non
         if self.idfn is None:
             return None
         try:
-            id = self.idfn(val)
+            id = self.idfn(val, argname, idx)
         except Exception as e:
             prefix = f"{self.nodeid}: " if self.nodeid is not None else ""
             msg = "error raised while trying to determine id of parameter '{}' at position {}"
@@ -963,12 +963,12 @@ def _idval_from_function(self, val: object, argname: str, idx: int) -> str | Non
             return None
         return self._idval_from_value(id)
 
-    def _idval_from_hook(self, val: object, argname: str) -> str | None:
+    def _idval_from_hook(self, val: object, argname: str, idx: int) -> str | None:
         """Try to make an ID for a parameter in a ParameterSet by calling the
         :hook:`pytest_make_parametrize_id` hook."""
         if self.config:
             id: str | None = self.config.hook.pytest_make_parametrize_id(
-                config=self.config, val=val, argname=argname
+                config=self.config, val=val, argname=argname, idx=idx
             )
             return id
         return None
@@ -1136,7 +1136,9 @@ def parametrize(
         argnames: str | Sequence[str],
         argvalues: Iterable[ParameterSet | Sequence[object] | object],
         indirect: bool | Sequence[str] = False,
-        ids: Iterable[object | None] | Callable[[Any], object | None] | None = None,
+        ids: Iterable[object | None]
+        | Callable[[Any, str, int], object | None]
+        | None = None,
         scope: _ScopeName | None = None,
         *,
         _param_mark: Mark | None = None,
@@ -1315,7 +1317,7 @@ def parametrize(
     def _resolve_parameter_set_ids(
         self,
         argnames: Sequence[str],
-        ids: Iterable[object | None] | Callable[[Any], object | None] | None,
+        ids: Iterable[object | None] | Callable[[Any, str, int], object | None] | None,
         parametersets: Sequence[ParameterSet],
         nodeid: str,
     ) -> list[str]:
diff --git a/src/_pytest/setuponly.py b/src/_pytest/setuponly.py
index de297f408d3..c9bac4bfa66 100644
--- a/src/_pytest/setuponly.py
+++ b/src/_pytest/setuponly.py
@@ -41,7 +41,11 @@ def pytest_fixture_setup(
                 # display it now and during the teardown (in .finish()).
                 if fixturedef.ids:
                     if callable(fixturedef.ids):
-                        param = fixturedef.ids(request.param)
+                        param = fixturedef.ids(
+                            request.param,
+                            request.fixturename or "",
+                            request.param_index,
+                        )
                     else:
                         param = fixturedef.ids[request.param_index]
                 else:
diff --git a/testing/python/metafunc.py b/testing/python/metafunc.py
index 2dd85607e71..3ffb843e462 100644
--- a/testing/python/metafunc.py
+++ b/testing/python/metafunc.py
@@ -514,7 +514,7 @@ def test_idmaker_enum(self) -> None:
     def test_idmaker_idfn(self) -> None:
         """#351"""
 
-        def ids(val: object) -> str | None:
+        def ids(val: object, argname: str, idx: int) -> str | None:
             if isinstance(val, Exception):
                 return repr(val)
             return None
@@ -537,7 +537,7 @@ def ids(val: object) -> str | None:
     def test_idmaker_idfn_unique_names(self) -> None:
         """#351"""
 
-        def ids(val: object) -> str:
+        def ids(val: object, argname: str, idx: int) -> str:
             return "a"
 
         result = IdMaker(
@@ -585,7 +585,7 @@ def getini(self, name):
             result = IdMaker(
                 ("a",),
                 [pytest.param("string")],
-                lambda _: "ação",
+                lambda _, __, ___: "ação",
                 None,
                 config,
                 None,
diff --git a/testing/typing_checks.py b/testing/typing_checks.py
index d4d6a97aea6..e575fbe7d63 100644
--- a/testing/typing_checks.py
+++ b/testing/typing_checks.py
@@ -8,6 +8,9 @@
 from __future__ import annotations
 
 import contextlib
+from typing import Any
+from typing import Callable
+from typing import cast
 from typing import Optional
 
 from typing_extensions import assert_type
@@ -23,7 +26,12 @@ def check_mark_xfail_raises() -> None:
 
 
 # Issue #7494.
-@pytest.fixture(params=[(0, 0), (1, 1)], ids=lambda x: str(x[0]))
+@pytest.fixture(
+    params=[(0, 0), (1, 1)],
+    ids=cast(
+        Callable[[Any, str, int], object | None] | None, lambda x, _, __: str(x[0])
+    ),
+)
 def check_fixture_ids_callable() -> None:
     pass