What's the tie up ID3D11DeviceContext::PSSetShaderResource() - direct3d11

PSSetShaderResource()'s first parameter:
void PSSetShaderResources(
[in] UINT StartSlot,
[in] UINT NumViews,
[in] ID3D11ShaderResourceView *const *ppShaderResourceViews
);
StartSlot: "Index into the device's zero-based array to begin setting shader resources"
So what's the tie up between integer indices and your .hlsl variables? In d3d9, everything was by string-based name. Now these integer indices seem to have something missing......
Say you have one shader file:
// shader_1.psh
Texture2D tex ;
And another..
// shader_2.psh
TextureCube cubeTex ;
If you're only using shader_1.psh, how do you distinguish between them when they are in separate files?
// something like this..
d3d11devicecontext->PSSetShaderResources( 0, 1, &texture2d ) ;
// index 0 sets 0th texture..
// what index is the tex cube?

This is still an experimentally verified guess (didn't find reference documentation), but I believe you can do it like so:
// HLSL shader
Texture2D tex : register( t0 );
Texture2D cubeTex : register( t1 );
SamplerState theSampler : register( s0 );
So now, from the C++ code, to bind a D3D11Texture2D* to tex in the shader, the tie up is:
// C++
d3d11devicecontext->PSSetShaderResources( 0, 1, &texture2d ) ; // SETS TEX # register( t0 )
d3d11devicecontext->PSSetShaderResources( 1, 1, &textureCUBE ) ;//SETS TEX # register( t1 )

Related

How do I extract the output from CGAL::poisson_surface_reconstruction_delaunay?

I am trying to convert a point cloud to a trimesh using CGAL::poisson_surface_reconstruction_delaunay() and extract the data inside the trimesh to an OpenGL friendly format:
// The function below should set vertices and indices so that:
// triangle 0: (vertices[indices[0]],vertices[indices[1]],vertices[indices[2]]),
// triangle 1: (vertices[indices[3]],vertices[indices[4]],vertices[indices[5]])
// ...
// triangle n - 1
void reconstructPointsToSurfaceInOpenGLFormat(const& std::list<std::pair<Kernel::Point_3, Kernel::Vector_3>> points, // input: points and normals
std::vector<glm::vec3>& vertices, // output
std::vector<unsigned int>& indices) { // output
CGAL::Surface_mesh<Kernel::Point_3> trimesh;
double spacing = 10;
bool ok = CGAL::poisson_surface_reconstruction_delaunay(points.begin(), points.end(),
CGAL::First_of_pair_property_map<std::pair<Kernel::Point_3, Kernel::Vector_3>>(),
CGAL::Second_of_pair_property_map<std::pair<Kernel::Point_3, Kernel::Vector_3>>(),
trimesh, spacing);
// How do I set the vertices and indices values?
}
Please help me on iterating trough the triangles in trimesh and setting the vertices and indices in the code above.
The class Polyhedron_3 is not indexed based so you need to provide a item class with ids like Polyhedron_items_with_id_3. You will then need to call CGAL::set_halfedgeds_items_id(trimesh) to init the ids. If you can't modify the Polyhedron type, then you can use dynamic properties and will need to init the ids.
Note that Surface_mesh is indexed based and no particular handling is needed to get indices.
Based on sloriots code from his answer:
void mesh2GLM(CGAL::Surface_mesh<Kernel::Point_3>& trimesh, std::vector<glm::vec3>& vertices, std::vector<int>& indices) {
std::map<size_t, size_t> meshIndex2Index;
// Loop over all vertices in mesh:
size_t index = 0;
for (Mesh::Vertex_index v : CGAL::vertices(trimesh)) {
CGAL::Epick::Point_3 point = trimesh.point(v);
std::size_t vi = v;
vertices.push_back(glm::vec3(point.x(), point.y(), point.z()));
meshIndex2Index[vi] = index;
index++;
}
// Loop over all triangles (faces):
for (Mesh::Face_index f : faces(trimesh)) {
for (Mesh::Vertex_index v : CGAL::vertices_around_face(CGAL::halfedge(f, trimesh), trimesh)) {
trimesh.point(v);
std::size_t vi = v;
size_t index = meshIndex2Index[vi];
indices.push_back(index);
}
}
}
Seems to work fine.

Compile error when trying to access StructuredBuffer

I want to access a StructuredBuffer<int>in a compute shader but I get the error:
Shader error in 'Particle.compute': array, matrix, vector, or indexable object type expected in index expression at Particle.compute(28) (on d3d11)
The code:
#pragma kernel CSMain
#include "Assets/Uplus/ZCommon/Resources/ImageProcessing/UplusDirectCompute.cginc"
struct Particle
{
float3 Position;
float Mass;
};
Texture2D<float2> _terTx;
ConsumeStructuredBuffer<Particle> currentBuffer;
AppendStructuredBuffer<Particle> nextBuffer;
StructuredBuffer<int> particleCount;
float3 _terPos;
float _terSize, _terPhysicalScale, _resolution;
SamplerState _LinearClamp;
SamplerState _LinearRepeat;
#define _gpSize 512
[numthreads(_gpSize, 1, 1)]
void CSMain(uint3 dispatchID : SV_DispatchThreadID)
{
int flatID = dispatchID.x;
int particleCount = particleCount[0];
if (flatID >= particleCount) return;
Particle particle = currentBuffer.Consume();
//Commented the rest of code
nextBuffer.Append(particle);
}
The error points the line int particleCount = particleCount[0];. Why is that?
The whole idea behind the shader is we have two buffers. We fill one with some data (we call each of them Particle) from CPU and then in the shader consume the data from the buffer, process it and then append to another buffer. then we swap buffers and do another iteration. The particleCount buffer holds the current count of Particles that the buffer holds and the if clause prevents from consuming more Particles than available.
This is an old question so I assume you solved it, but here is the answer anyway:
You are declaring particleCount as an int when it already is a buffer.
Either change the name to int currentParticleCount = particleCount[0]; or just don't use a temporary variable:
if (flatID >= particleCount[0]) return;

"Hello TensorFlow!" using the C API

For learning purposes, how to code this Python example using the TensorFlow C API ?
import tensorflow as tf
hello = tf.constant("hello TensorFlow!")
sess=tf.Session()
print(sess.run(hello))
I have tried it this way:
#include <string.h>
#include <iostream.h>
#include "c_api.h"
int main( int argc, char ** argv )
{
TF_Graph * graph = TF_NewGraph();
TF_SessionOptions * options = TF_NewSessionOptions();
TF_Status * status = TF_NewStatus();
TF_Session * session = TF_NewSession( graph, options, status );
char hello[] = "Hello TensorFlow!";
TF_Tensor * tensor = TF_AllocateTensor( TF_STRING, 0, 0, 8 + TF_StringEncodedSize( strlen( hello ) ) );
TF_OperationDescription * operationDescription = TF_NewOperation( graph, "Const", "hello" );
TF_Operation * operation;
struct TF_Output * output;
TF_StringEncode( hello, strlen( hello ), 8 + ( char * ) TF_TensorData( tensor ), TF_StringEncodedSize( strlen( hello ) ), status );
TF_SetAttrTensor( operationDescription, "value", tensor, status );
TF_SetAttrType( operationDescription, "dtype", TF_TensorType( tensor ) );
operation = TF_FinishOperation( operationDescription, status );
output->oper = operation;
output->index = 0;
TF_SessionRun( session, 0,
0, 0, 0, // Inputs
output, &tensor, 1, // Outputs
&operation, 1, // Operations
0, status );
printf( "%i", TF_GetCode( status ) );
TF_CloseSession( session, status );
TF_DeleteSession( session, status );
TF_DeleteStatus( status );
TF_DeleteSessionOptions( options );
return 0;
}
I am testing it on Windows using the TensorFlow.dll from:
http://ci.tensorflow.org/view/Nightly/job/nightly-libtensorflow-windows/lastSuccessfulBuild/artifact/lib_package/libtensorflow-cpu-windows-x86_64.zip
The above code GPFs on the TF_SessionRun() call. Once we find a solution for that, how to retrieve the output ? Should a different tensor be used for the
output ? The above code reuses it in both the output and the operation.
many thanks
There was a bug to solve beside the offset initialization. This version seems to work fine:
#include <iostream.h>
#include "c_api.h"
int main( int argc, char ** argv )
{
TF_Graph * graph = TF_NewGraph();
TF_SessionOptions * options = TF_NewSessionOptions();
TF_Status * status = TF_NewStatus();
TF_Session * session = TF_NewSession( graph, options, status );
char hello[] = "Hello TensorFlow!";
TF_Tensor * tensor = TF_AllocateTensor( TF_STRING, 0, 0, 8 + TF_StringEncodedSize( strlen( hello ) ) );
TF_Tensor * tensorOutput;
TF_OperationDescription * operationDescription = TF_NewOperation( graph, "Const", "hello" );
TF_Operation * operation;
struct TF_Output output;
TF_StringEncode( hello, strlen( hello ), 8 + ( char * ) TF_TensorData( tensor ), TF_StringEncodedSize( strlen( hello ) ), status );
memset( TF_TensorData( tensor ), 0, 8 );
TF_SetAttrTensor( operationDescription, "value", tensor, status );
TF_SetAttrType( operationDescription, "dtype", TF_TensorType( tensor ) );
operation = TF_FinishOperation( operationDescription, status );
output.oper = operation;
output.index = 0;
TF_SessionRun( session, 0,
0, 0, 0, // Inputs
&output, &tensorOutput, 1, // Outputs
&operation, 1, // Operations
0, status );
printf( "status code: %i\n", TF_GetCode( status ) );
printf( "%s\n", ( ( char * ) TF_TensorData( tensorOutput ) ) + 9 );
TF_CloseSession( session, status );
TF_DeleteSession( session, status );
TF_DeleteStatus( status );
TF_DeleteSessionOptions( options );
return 0;
}
Do we have to delete the tensorOutput ? Not sure why we have to add 9 (instead of 8) to get the beginning of the string.
TF_STRING tensors are encoded using the format described here. In your code, you accounted for space (8 bytes) to encode the one offset, but didn't actually initialize it. To do that, you'd want to add something like:
memset(TF_TensorData(tensor), 0, 8);
Before the call to TF_SetAttrTensor, as that will set the "offset" of the string element to 0 (which the where you're encoding the one string value).
To your second question: You aren't actually re-using the same tensor pointer. The comments for TF_SessionRun suggest that TF_SessionRun is allocating a new TF_Tensor object that the caller takes ownership of. So, in your code snippet, the tensor variable is being overwritten to point to a newly allocated tensor.
Hope that helps.
The example will work on Linux with TensorFlow installed as described here https://www.tensorflow.org/install/lang_c with changed include directives:
#include <stdio.h>
#include <string.h>
#include <tensorflow/c/c_api.h>
To build it is enough to execute
gcc hello_tf.c -ltensorflow -o hello_tf
as it was said in TensorFlow docs.

STM32: non-initialized variables?

using the uvision IDE for STM32 development, I want to have some timer variables not initialized at startup. I have tried:
volatile unsigned int system_time __attribute__((section(".noinit")));
and
__attribute__((zero_init)) volatile int system_timer;
but nothing seems to work. Following the hints from elswhere, I have additionally checked NoInit at options/target/IRAM1.
Still, the variables are set to zero after reset.
Can anybody help?
You need to follow these steps.
declare your variable as follows:
volatile unsigned int system_time __attribute__((section(".noinit"),zero_init));
Then you have to use a scatter file to declare the execution section with the NOINIT attribute and use it with the linker.
example scatter file:
LR_IROM1 0x08000000 0x00080000 { ; load region size_region
ER_IROM1 0x08000000 0x00080000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_IRAM1 0x20000000 UNINIT 0x00000100 { ;no init section
*(.noinit)
}
RW_IRAM2 0x20000100 0x0000FFF0 { ;all other rw data
.ANY(+RW +ZI)
}
}
You have to check the address of that variable from .MAP file and use the The at keyword
allows you to specify the address for uninitialized variables in your C source files. The
following example demonstrates how to locate several different variable types using the at keyword.for example......
struct link {
struct link idata *next;
char code *test;
};
struct link idata list _at_ 0x40; /* list at idata 0x40 */
char xdata text[256] _at_ 0xE000; /* array at xdata 0xE000 */
int xdata i1 _at_ 0x8000; /* int at xdata 0x8000 */
char far ftext[256] _at_ 0x02E000; /* array at xdata 0x03E000 */
void main ( void ) {
link.next = (void *) 0;
i1 = 0x1234;
text [0] = 'a';
ftext[0] = 'f';
}
I hope it helps for solving your problem.

Trying to parse OpenCV YAML ouput with yaml-cpp

I've got a series of OpenCv generated YAML files and would like to parse them with yaml-cpp
I'm doing okay on simple stuff, but the matrix representation is proving difficult.
# Center of table
tableCenter: !!opencv-matrix
rows: 1
cols: 2
dt: f
data: [ 240, 240]
This should map into the vector
240
240
with type float. My code looks like:
#include "yaml.h"
#include <fstream>
#include <string>
struct Matrix {
int x;
};
void operator >> (const YAML::Node& node, Matrix& matrix) {
unsigned rows;
node["rows"] >> rows;
}
int main()
{
std::ifstream fin("monsters.yaml");
YAML::Parser parser(fin);
YAML::Node doc;
Matrix m;
doc["tableCenter"] >> m;
return 0;
}
But I get
terminate called after throwing an instance of 'YAML::BadDereference'
what(): yaml-cpp: error at line 0, column 0: bad dereference
Abort trap
I searched around for some documentation for yaml-cpp, but there doesn't seem to be any, aside from a short introductory example on parsing and emitting. Unfortunately, neither of these two help in this particular circumstance.
As I understand, the !! indicate that this is a user-defined type, but I don't see with yaml-cpp how to parse that.
You have to tell yaml-cpp how to parse this type. Since C++ isn't dynamically typed, it can't detect what data type you want and create it from scratch - you have to tell it directly. Tagging a node is really only for yourself, not for the parser (it'll just faithfully store it for you).
I'm not really sure how an OpenCV matrix is stored, but if it's something like this:
class Matrix {
public:
Matrix(unsigned r, unsigned c, const std::vector<float>& d): rows(r), cols(c), data(d) { /* init */ }
Matrix(const Matrix&) { /* copy */ }
~Matrix() { /* delete */ }
Matrix& operator = (const Matrix&) { /* assign */ }
private:
unsigned rows, cols;
std::vector<float> data;
};
then you can write something like
void operator >> (const YAML::Node& node, Matrix& matrix) {
unsigned rows, cols;
std::vector<float> data;
node["rows"] >> rows;
node["cols"] >> cols;
node["data"] >> data;
matrix = Matrix(rows, cols, data);
}
Edit It appears that you're ok up until here; but you're missing the step where the parser loads the information into the YAML::Node. Instead, se it like:
std::ifstream fin("monsters.yaml");
YAML::Parser parser(fin);
YAML::Node doc;
parser.GetNextDocument(doc); // <-- this line was missing!
Matrix m;
doc["tableCenter"] >> m;
Note: I'm guessing dt: f means "data type is float". If that's the case, it'll really depend on how the Matrix class handles this. If you have a different class for each data type (or a templated class), you'll have to read that field first, and then choose which type to instantiate. (If you know it'll always be float, that'll make your life easier, of course.)