Python GPU: expose GPU functions in Python #108668

Open
jon denning wants to merge 10 commits from gfxcoder/blender:gpu_state_updates into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
Member

Several functions in GPU module were not yet exposed to Python.

  • Enable depth writing using DepthWrite on an instance of GPUShaderCreateInfo
  • Read current and set depth range
  • Read if scissor testing is currently enabled

Fixed documentation for define method on GPUShaderCreateInfo.

Several functions in GPU module were not yet exposed to Python. - Enable depth writing using `DepthWrite` on an instance of `GPUShaderCreateInfo` - Read current and set depth range - Read if scissor testing is currently enabled Fixed documentation for `define` method on `GPUShaderCreateInfo`.
jon denning added 3 commits 2023-06-06 17:16:13 +02:00
Several functions in GPU module were not yet exposed to Python.

- Enable depth writing using `DepthWrite` on an instance of
  `GPUShaderCreateInfo`.
- Read current and set depth range.
- Read if scissor testing is enabled.

Fixed documentation for `define` method on `GPUShaderCreateInfo`.
Function declaration was missing `void` in arglist to make it a proper
function template.
jon denning requested review from Sybren A. Stüvel 2023-06-06 17:17:38 +02:00
jon denning requested review from Campbell Barton 2023-06-06 17:17:38 +02:00
Author
Member

I followed the instructions on https://wiki.blender.org/wiki/Tools/Pull_Requests as best I could. Please let me know if this PR needs to be updated before reviewing.

I followed the instructions on https://wiki.blender.org/wiki/Tools/Pull_Requests as best I could. Please let me know if this PR needs to be updated before reviewing.
Author
Member

A note: as of Blender 3.6.0, there is no way to create a shader in Python that updates the depth in fragment shader. This commit exposes that ability.

A note: as of Blender 3.6.0, there is _no_ way to create a shader in Python that updates the depth in fragment shader. This commit exposes that ability.
Sybren A. Stüvel removed the
Interest
Python API
label 2023-06-06 18:04:32 +02:00

Could you provide a way to test the changes?

Could you provide a way to test the changes?
jon denning added 1 commit 2023-06-06 21:55:23 +02:00
`p` is for int, but `f` is for float.
Author
Member

First, I noticed and fixed a bug in the depth_range_set function. This change is in commit 4e6fcb4349.

Attached is a Python script to demo the depth_range_set and write_depth functions. There is some boiler/helper code in the script to simplify iteration and to handle errors gracefully. I can strip it down to individual tests if needed. It can run in Blender 3.6.0 beta (although the features do not work), 4.0.0 alpha (although features don't work), and this branch.

The two getter functions can be easily tested from Python console...

gpu.state.scissor_test_set(True) ; print(gpu.state.scissor_test_get())  # should be True
gpu.state.scissor_test_set(False) ; print(gpu.state.scissor_test_get())  # should be False

gpu.state.depth_range_set(0.0, 1.0) ; print(gpu.state.depth_range_get())  # should be (0.0, 1.0)
gpu.state.depth_range_set(0.1, 0.9) ; print(gpu.state.depth_range_get())  # should be (0.1, 0.9)

image

First, I noticed and fixed a bug in the `depth_range_set` function. This change is in commit 4e6fcb4349. Attached is a Python script to demo the `depth_range_set` and `write_depth` functions. There is some boiler/helper code in the script to simplify iteration and to handle errors gracefully. I can strip it down to individual tests if needed. It can run in Blender 3.6.0 beta (although the features do not work), 4.0.0 alpha (although features don't work), and this branch. The two getter functions can be easily tested from Python console... ``` gpu.state.scissor_test_set(True) ; print(gpu.state.scissor_test_get()) # should be True gpu.state.scissor_test_set(False) ; print(gpu.state.scissor_test_get()) # should be False gpu.state.depth_range_set(0.0, 1.0) ; print(gpu.state.depth_range_get()) # should be (0.0, 1.0) gpu.state.depth_range_set(0.1, 0.9) ; print(gpu.state.depth_range_get()) # should be (0.1, 0.9) ``` ![image](/attachments/9de929f3-8113-4479-b438-bb914535672a)
Campbell Barton requested changes 2023-06-07 09:04:45 +02:00
@ -520,0 +548,4 @@
Py_RETURN_NONE;
}
// .depth_write(DepthWrite::ANY))

Should be removed?

Should be removed?
gfxcoder marked this conversation as resolved
@ -935,3 +968,3 @@
".. code-block:: glsl\n"
"\n"
" #define name value\n"
" \"#define name value\"\n"

This doesn't seem related, the code-block should not need to be quoted AFAICS.

This doesn't seem related, the code-block should not need to be quoted AFAICS.
Author
Member

Ah, I was following the example of doc for fragment_source, which I notice now also has the quotes but should not. I think it just needs indented.

I looked at the markup style guide, but the code samples section was a bit sparse on formatting details.

will get this (and other parts that use incorrect formatting) fixed. should these changes be in a separate PR rather than a general Python / GPU improvement PR?

Ah, I was following the example of doc for [fragment_source](https://docs.blender.org/api/current/gpu.types.html#gpu.types.GPUShaderCreateInfo.fragment_source), which I notice now also has the quotes but should not. I think it just needs indented. I looked at the [markup style guide](https://docs.blender.org/manual/en/dev/contribute/guides/markup_guide.html), but the [code samples](https://docs.blender.org/manual/en/dev/contribute/guides/markup_guide.html#code-samples) section was a bit sparse on formatting details. will get this (and other parts that use incorrect formatting) fixed. should these changes be in a separate PR rather than a general Python / GPU improvement PR?

These documented by https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#directive-code-block - so unless the string is expected to be quoted (when displayed in the web-page), additional quotes should not be added.

These documented by https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#directive-code-block - so unless the string is expected to be quoted (when displayed in the web-page), additional quotes should not be added.
Author
Member

These extraneous quotes are removed in this PR.

These extraneous quotes are removed in this PR.
gfxcoder marked this conversation as resolved
@ -298,0 +317,4 @@
static PyObject *pygpu_state_depth_range_set(PyObject *UNUSED(self), PyObject *args)
{
float near, far;
if (!PyArg_ParseTuple(args, "ff:depth_range_set", &near, &far)) {

There is no check that near <= far. If flipping near/far results in unexpected/buggy behavior, it's probably best to raise an exception in this case.
Or, if there is some reason to allow it, that should be noted in the code-comments, possibly the doc-string.

There is no check that `near <= far`. If flipping near/far results in unexpected/buggy behavior, it's probably best to raise an exception in this case. Or, if there is some reason to allow it, that should be noted in the code-comments, possibly the doc-string.
gfxcoder marked this conversation as resolved
@ -298,0 +330,4 @@
"\n"
" Current mapping of depth values from normalized device coordinates to window coordinates.\n"
"\n"
" :return: The depth range as a tuple\n"

picky as a tuple is repeated information, may as well leave it out.

*picky* `as a tuple` is repeated information, may as well leave it out.
Author
Member

I was following example of scissor_get. Should docs for both remove the as a tuple?

I was following example of [scissor_get](https://docs.blender.org/api/current/gpu.state.html#gpu.state.scissor_get). Should docs for both remove the `as a tuple`?

Wasn't aware of that, may as well, yes.

Wasn't aware of that, may as well, yes.
Author
Member

Removed as a tuple and made some additional adjustment to docstring.

Removed `as a tuple` and made some additional adjustment to docstring.
gfxcoder marked this conversation as resolved
Author
Member

Attached is a better version of testing code. Rather than rendering two triangles with coincident points, here it renders two coplanar triangles. The Z-fighting is very evident and an effect that should be avoided is most cases.

Attached is a _better_ version of testing code. Rather than rendering two triangles with coincident points, here it renders two coplanar triangles. The Z-fighting is very evident and an effect that should be avoided is most cases.
jon denning added 2 commits 2023-06-07 15:37:32 +02:00
- Removed extraneous commented-out code
- Corrected Python docs for several functions
- Raising exception when `near > far`
jon denning added 2 commits 2023-06-08 15:49:05 +02:00
Removed `as a tuple` from docstring for `pygpu_state_scissor_get_doc`
and `pygpu_state_depth_range_get_doc`
Campbell Barton approved these changes 2023-06-09 03:50:45 +02:00
Campbell Barton left a comment
Owner

Minor requests, otherwise LGTM.

Minor requests, otherwise LGTM.
@ -298,0 +321,4 @@
}
if (near > far) {
PyErr_SetString(PyExc_ValueError, "Near must be less than or equal to far");

Return NULL after setting the error.
Should this raise an exception for negative values too?

Return `NULL` after setting the error. Should this raise an exception for negative values too?
Author
Member

Values over 1 don't make sense either. Should we test against these? Do these tests need to be reported in the docstring?

Values over 1 don't make sense either. Should we test against these? Do these tests need to be reported in the docstring?
Author
Member

added checks for negative values and for too positive (>1) values.

added checks for negative values and for too positive (>1) values.
gfxcoder marked this conversation as resolved
jon denning added 2 commits 2023-06-09 17:18:19 +02:00
- should return NULL if exception occurs
- near and far values should be between 0 and 1
Author
Member

This PR is applied to Blender 4.0. Is there any way to get these changes into 3.6? even if 3.6.1?

Thanks for the review+feedback @dr.sybren and @ideasman42!

This PR is applied to Blender 4.0. Is there any way to get these changes into 3.6? even if 3.6.1? Thanks for the review+feedback @dr.sybren and @ideasman42!
Sybren A. Stüvel requested changes 2023-09-26 11:32:28 +02:00
Sybren A. Stüvel left a comment
Member

I've tried building this PR, but I get these errors:

blender/source/blender/python/gpu/gpu_py_state.cc:304:64: error: unknown type name 'self'
static PyObject *pygpu_state_scissor_test_get(PyObject *UNUSED(self))
                                                               ^
blender/source/blender/python/gpu/gpu_py_state.cc:304:57: warning: unused parameter 'UNUSED' [-Wunused-parameter]
static PyObject *pygpu_state_scissor_test_get(PyObject *UNUSED(self))
                                                        ^
blender/source/blender/python/gpu/gpu_py_state.cc:316:63: error: unknown type name 'self'
static PyObject *pygpu_state_depth_range_set(PyObject *UNUSED(self), PyObject *args)
                                                              ^
blender/source/blender/python/gpu/gpu_py_state.cc:316:56: warning: unused parameter 'UNUSED' [-Wunused-parameter]
static PyObject *pygpu_state_depth_range_set(PyObject *UNUSED(self), PyObject *args)
                                                       ^
blender/source/blender/python/gpu/gpu_py_state.cc:344:63: error: unknown type name 'self'
static PyObject *pygpu_state_depth_range_get(PyObject *UNUSED(self))
                                                              ^
blender/source/blender/python/gpu/gpu_py_state.cc:344:56: warning: unused parameter 'UNUSED' [-Wunused-parameter]
static PyObject *pygpu_state_depth_range_get(PyObject *UNUSED(self))
                                                       ^
3 warnings and 3 errors generated.
[198/1682] Building CXX object source/blender/gpu/CMakeFiles/bf_gpu.dir/intern/gpu_shader_create_info.cc.o

It probably needs some updating to work against current main.

I've tried building this PR, but I get these errors: ``` blender/source/blender/python/gpu/gpu_py_state.cc:304:64: error: unknown type name 'self' static PyObject *pygpu_state_scissor_test_get(PyObject *UNUSED(self)) ^ blender/source/blender/python/gpu/gpu_py_state.cc:304:57: warning: unused parameter 'UNUSED' [-Wunused-parameter] static PyObject *pygpu_state_scissor_test_get(PyObject *UNUSED(self)) ^ blender/source/blender/python/gpu/gpu_py_state.cc:316:63: error: unknown type name 'self' static PyObject *pygpu_state_depth_range_set(PyObject *UNUSED(self), PyObject *args) ^ blender/source/blender/python/gpu/gpu_py_state.cc:316:56: warning: unused parameter 'UNUSED' [-Wunused-parameter] static PyObject *pygpu_state_depth_range_set(PyObject *UNUSED(self), PyObject *args) ^ blender/source/blender/python/gpu/gpu_py_state.cc:344:63: error: unknown type name 'self' static PyObject *pygpu_state_depth_range_get(PyObject *UNUSED(self)) ^ blender/source/blender/python/gpu/gpu_py_state.cc:344:56: warning: unused parameter 'UNUSED' [-Wunused-parameter] static PyObject *pygpu_state_depth_range_get(PyObject *UNUSED(self)) ^ 3 warnings and 3 errors generated. [198/1682] Building CXX object source/blender/gpu/CMakeFiles/bf_gpu.dir/intern/gpu_shader_create_info.cc.o ``` It probably needs some updating to work against current `main`.
This pull request has changes conflicting with the target branch.
  • source/blender/gpu/GPU_state.h
  • source/blender/python/gpu/gpu_py_shader_create_info.cc
  • source/blender/python/gpu/gpu_py_state.c

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u gpu_state_updates:gfxcoder-gpu_state_updates
git checkout gfxcoder-gpu_state_updates
Sign in to join this conversation.
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset System
Interest
Audio
Interest
Automated Testing
Interest
Blender Asset Bundle
Interest
BlendFile
Interest
Collada
Interest
Compatibility
Interest
Compositing
Interest
Core
Interest
Cycles
Interest
Dependency Graph
Interest
Development Management
Interest
EEVEE
Interest
EEVEE & Viewport
Interest
Freestyle
Interest
Geometry Nodes
Interest
Grease Pencil
Interest
ID Management
Interest
Images & Movies
Interest
Import Export
Interest
Line Art
Interest
Masking
Interest
Metal
Interest
Modeling
Interest
Modifiers
Interest
Motion Tracking
Interest
Nodes & Physics
Interest
OpenGL
Interest
Overlay
Interest
Overrides
Interest
Performance
Interest
Physics
Interest
Pipeline, Assets & IO
Interest
Platforms, Builds & Tests
Interest
Python API
Interest
Render & Cycles
Interest
Render Pipeline
Interest
Sculpt, Paint & Texture
Interest
Text Editor
Interest
Translations
Interest
Triaging
Interest
Undo
Interest
USD
Interest
User Interface
Interest
UV Editing
Interest
VFX & Video
Interest
Video Sequencer
Interest
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
Legacy
Asset Browser Project
Legacy
Blender 2.8 Project
Legacy
Milestone 1: Basic, Local Asset Browser
Legacy
OpenGL Error
Meta
Good First Issue
Meta
Papercut
Meta
Retrospective
Meta
Security
Module
Animation & Rigging
Module
Core
Module
Development Management
Module
EEVEE & Viewport
Module
Grease Pencil
Module
Modeling
Module
Nodes & Physics
Module
Pipeline, Assets & IO
Module
Platforms, Builds & Tests
Module
Python API
Module
Render & Cycles
Module
Sculpt, Paint & Texture
Module
Triaging
Module
User Interface
Module
VFX & Video
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Priority
High
Priority
Low
Priority
Normal
Priority
Unbreak Now!
Status
Archived
Status
Confirmed
Status
Duplicate
Status
Needs Info from Developers
Status
Needs Information from User
Status
Needs Triage
Status
Resolved
Type
Bug
Type
Design
Type
Known Issue
Type
Patch
Type
Report
Type
To Do
No Milestone
No project
No Assignees
3 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: blender/blender#108668
No description provided.